2016-04-21 28 views
3

我有这个疑问:的MySQL优化SELECT COUNT不同的组由

SELECT `variationID`, count(DISTINCT(`userID`)) 
FROM data WHERE `testID` = XXXX AND `visit` = 1 GROUP BY `variationID` 
; 

这需要花费大量的时间来query.How我可以加快查询。

SELECT_TYPE表型possible_keys键key_len REF行 过滤额外SIMPLE数据
REF dc3_testIDPage,dc3_testIDvarIDPage,user_test_varID_url
dc3_testIDvarIDPage 8常量33106102 100.00使用其中

这是创建表的输出:

CREATE TABLE `data` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `userID` bigint(17) NOT NULL, 
    `testID` bigint(20) NOT NULL, 
    `variationID` bigint(20) NOT NULL, 
    `url` bigint(20) NOT NULL, 
    `time` bigint(20) NOT NULL, 
    `visit` bigint(20) NOT NULL DEFAULT '1', 
    `isTestPage` tinyint(1) NOT NULL, 
    PRIMARY KEY (`id`,`testID`), 
    KEY `url` (`url`), 
    KEY `dc3_testIDPage` (`testID`,`url`), 
    KEY `dc3_testIDvarIDPage` (`testID`,`variationID`,`url`), 
    KEY `user_test_url` (`userID`,`testID`,`url`), 
    KEY `user_test_varID_url` (`userID`,`testID`,`variationID`,`url`) 
) ENGINE=InnoDB AUTO_INCREMENT=67153224 DEFAULT CHARSET=latin1 
+0

欢迎来到Stack Overflow。感谢您发布EXPLAIN计划。你还可以编辑你的帖子以添加来自'SHOW CREATE TABLE data'的输出吗?要将其格式化为代码块,请突出显示它并使用'ctl-k'或'{}'编辑器工具栏按钮。 –

回答

1

最简单的事情你可以做的加快你的查询,以确保你没有做全表扫描。 where子句中的所有列应出现在索引中。所以在你的情况下,testID和visit应该有索引,甚至更好,你可以用testID和visit创建一个索引。如果访问是一个真/假布尔值,将不会缩小索引搜索的范围,但testID当然会。

创建索引文件是在这里:http://dev.mysql.com/doc/refman/5.7/en/create-index.html

基于你的id和testID创建表是在一个单一的主键。添加一个只有testID的新密钥或索引。这应该会有所帮助。由于它看起来像访问不是一个布尔添加索引与访问和testID会给你最好的性能提升。

+0

感谢MBA,但在生产和空间方面,我们无法在数据库中添加更多索引;任何其他选项重新编写查询以获得更多性能? – oasi711

+0

@ oasi711只要全表扫描正在发生,全表扫描将主宰性能,您可以执行其他任何操作。我看到你有五个二级索引。你需要他们吗?如果空间也是一个主要考虑因素,那么我会建议分析哪些指数最重要并优先考虑。 – mba12