【问题标题】:restriction on group by column限制按列分组
【发布时间】:2016-11-07 21:39:40
【问题描述】:

我在 MySQL 中有以下表格和查询:

CREATE TABLE IF NOT EXISTS `events` (
  `pv_name` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
  `time_stamp` bigint(20) unsigned NOT NULL,
  `event_type` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
  `data` json,
  PRIMARY KEY (`pv_name`,`time_stamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED;

CREATE TEMPORARY TABLE matching_pv_names (
pv_name varchar(60) NOT NULL,
PRIMARY KEY (pv_name)
) ENGINE=Memory;

SELECT events.pv_name, MAX(events.time_stamp) AS time_stamp
FROM events
WHERE events.time_stamp <= @time_stamp_in
GROUP BY events.pv_name;

当前的查询通过“使用索引进行分组”有效地运行。是否可以对其进行修改以将其分组的 pv_names 集限制为 matching_pv_names 表中的 pv_names 集,并且仍然保留“使用索引进行分组”优化?例如,以下查询不再使用此优化:

SELECT events.pv_name, MAX(events.time_stamp) AS time_stamp
FROM events
WHERE events.time_stamp <= @time_stamp_in
AND events.pv_name IN (SELECT matching_pv_names.pv_name FROM matching_pv_names)
GROUP BY events.pv_name;

有没有别的写法?

【问题讨论】:

    标签: mysql group-by query-optimization


    【解决方案1】:

    您的第一个 SQL 可以从 GROUP BY 优化中受益,因为它只使用一个表,并且您用于 GROUP BY 的列上有索引,并且您使用的唯一聚合函数是 MAX()。并且在 WHERE 子句中使用常量。

    在查询中添加另一个表后,GROUP BY optimization 将无法应用。

    【讨论】:

    • 我认为你是对的。我希望有办法解决,因为我可以在查询中添加 WHERE events.pv_name LIKE 并保留优化。
    • 您不应该争取获得特定的优化,而应该争取“最佳”优化。
    • 我相信这是最好的优化,无论是在文档中还是在对我的数据集进行测试时。
    【解决方案2】:

    您询问了具体的优化问题,但真正的问题不是关于效率吗?

    看看效果如何:

    SELECT  e.pv_name, MAX(e.time_stamp) AS time_stamp
        FROM  events AS e
        JOIN  matching_pv_names AS m USING(pv_name)
        WHERE  e.time_stamp <= @time_stamp_in
        GROUP BY  e.pv_name;
    

    一种比较两个查询效率的方法,即使表很小,也是

    FLUSH STATUS;
    SELECT ...;
    SHOW SESSION STATUS LIKE 'Handler%';
    

    从历史上看,这个结构的优化很差:IN ( SELECT ... )。 (我不知道在您的版本中它是否对您的查询效果不佳。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-08
      • 2021-01-11
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 2016-11-01
      • 2020-02-29
      • 1970-01-01
      相关资源
      最近更新 更多