如何提高 COUNT(DISTINCT field1)... GROUP BY field2 的性能?
Posted
技术标签:
【中文标题】如何提高 COUNT(DISTINCT field1)... GROUP BY field2 的性能?【英文标题】:How to improve performance of COUNT(DISTINCT field1)... GROUP BY field2? 【发布时间】:2012-11-27 01:59:02 【问题描述】:我有以下问题
EXPLAIN SELECT COUNT(DISTINCT ip_address) as ip_address, exec_date
FROM requests
GROUP BY exec_date;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE requests range NULL daily_ips 263 NULL 488213 Using index for group-by (scanning)
带有覆盖索引daily_ips
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
requests 1 daily_ips 1 exec_date A 16 NULL NULL YES BTREE
requests 1 daily_ips 2 ip_address A 483492 NULL NULL YES BTREE
有什么办法可以进一步优化这个查询吗?
Using index for group-by (scanning)
到底是什么意思?这是否意味着整个GROUP BY
子句完全由索引完成,而语句的COUNT(DISTINCT ip_address)
部分则不是?
【问题讨论】:
【参考方案1】:根据您提供的数据,我看不出有任何方法可以进一步优化查询。
关于您的后续问题,mysql 的手册页描述了 Using index for group-by 的解释输出:
与Using index table access方法类似,Using index for group-by表示MySQL找到了一个索引,该索引可用于检索GROUP BY或DISTINCT查询的所有列,而无需对实际表进行任何额外的磁盘访问。此外,索引以最有效的方式使用,因此对于每个组,只读取几个索引条目。详情请见Section 8.13.10, “GROUP BY Optimization”。
您的索引特别适合加快查询速度。因为只选择了索引字段(查询中的每一列也出现在索引中),MySQL 甚至可能根本不需要命中表,因为所有相关数据都出现在索引中。
如果执行查询就像在 google 上执行搜索一样,想象一下不必点击任何链接的网站,因为您直接在搜索结果中找到了您正在寻找的信息 - 这有点像不需要扫描表数据就像。这里有更多关于how MySQL uses indexes的信息:
在某些情况下,可以优化查询以在不查阅数据行的情况下检索值。 (为查询提供所有必要结果的索引称为covering index。)如果查询仅使用表中的数字列并且构成某个键的最左前缀,则可以从更快的索引树:
SELECT key_part3 FROM tbl_name WHERE key_part1=1
【讨论】:
谢谢 Danny,出于好奇,有什么方法可以判断Using index for group-by (scanning)
是指应用于 GROUP-BY
还是 DISTINCT
子句的索引?
因为DISTINCT
只是a special case of GROUP BY
,而且由于两列来自同一个表、同一个索引,我真的不确定。【参考方案2】:
你可以对象化:
Objectify ofy = ObjectifyService.begin(); Query query = ofy.query(这里是类名.class).filter("表中的列名",要查询的值).list();
在此之前,您可能需要为 Objectify 添加 jar。
【讨论】:
以上是关于如何提高 COUNT(DISTINCT field1)... GROUP BY field2 的性能?的主要内容,如果未能解决你的问题,请参考以下文章
postgresql COUNT(DISTINCT ...) 非常慢
8InfluxDB常用函数聚合函数,count()函数,DISTINCT()函数,MEAN()函数,MEDIAN()函数,SPREAD()函数,SUM()函数
如何在 SQL Server 中使用带有框架的窗口函数执行 COUNT(DISTINCT)