2016-04-21 46 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