2015-04-22 99 views
0

做一個簡單的查詢像MySQL的很慢有20萬條記錄

select state, count(state) as cnt from big_data where status=0 group by state 

大約需要20秒。這裏是我的表格def:

CREATE TABLE `NewTable` (`id` bigint(22) NOT NULL AUTO_INCREMENT , 
          `city` varchar(32) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL , 
          `state` varchar(2) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL , 
          `miles_away` int(5) NOT NULL , 
          `member_id` int(11) NOT NULL , 
          `gender` varchar(17) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL , 
          `profile` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL , 
          `status` varchar(1) CHARACTER SET latin1       

    COLLATE latin1_swedish_ci NOT NULL , 
    PRIMARY KEY    (`id`, 
           `city`, 
           `state`, 
           `miles_away`, 
           `member_id`, 
           `gender`, 
           `profile`, 
           `status`), 
    UNIQUE INDEX `id` (`id`) USING BTREE , 
    UNIQUE INDEX `profile` (`profile`) USING BTREE , 
    INDEX `city` (`city`) USING BTREE , 
    INDEX `state` (`state`) USING BTREE , 
    INDEX `miles_away` (`miles_away`) USING BTREE , 
    INDEX `member_id` (`member_id`) USING BTREE , 
    INDEX `gender` (`gender`) USING BTREE , 
    INDEX `status` (`status`) USING BTREE) 
    ENGINE=InnoDB 
    DEFAULT CHARACTER SET=latin1 COLLATE=latin1_swedish_ci 
    AUTO_INCREMENT=12889691 
    ROW_FORMAT=COMPACT; 

即使是基於主鍵的簡單ID查找需要那麼長時間。我的服務器有72個內核(第4代至強ES2690與64GB RAM)

這裏解釋的截圖:

multi threads http://gaysugardaddyfinder.com/shot.PNG

幫助!

+0

這不是從EXPLAIN輸出。運行'EXPLAIN選擇狀態,計數(狀態)...'。這將顯示優化程序在聲明中所做的事情。另外,表中的主鍵是表中的所有列是非常奇怪的,特別是當你已經有一個非空的列,它有一個唯一的約束('id'),可以作爲主鍵。 – spencer7593

回答

1

使用EXPLAIN來顯示執行計劃。

參考:https://dev.mysql.com/doc/refman/5.5/en/using-explain.html

爲了獲得最佳性能,提供一個合適的索引,以便優化器能夠避免「使用文件排序」操作來滿足GROUP BY

我建議:

CREATE INDEX `NewTableIX1` ON `NewTable` (`status`,`state`) 

(我建議,因爲你的查詢包括在status列相等謂詞,它是由操作上state列執行組有了這個新的指標,我期望EXPLAIN輸出顯示它使用新索引,並且還顯示查詢完全從EXPLAIN輸出的額外列中顯示的索引 - 「使用索引」中滿足。)

在定義了這個新的索引之後,單獨的索引就是status列是多餘的,可以丟棄。


隨訪

由於id是獨一無二的,NOT NULL,它可以作爲表的主鍵。 PRIMARY KEY不需要在表格中包含每一列。 (二級索引將會和表本身一樣大,因爲PRIMARY KEY將被存儲在每個索引中,「指針」將返回到集羣索引。)

如果這是我的表, d放回這樣的:

PRIMARY KEY    (`id`, 
          `city`, 
          `state`, 
          `miles_away`, 
          `member_id`, 
          `gender`, 
          `profile`, 
          `status`), 
UNIQUE INDEX `id` (`id`) USING BTREE , 

通過如此:

PRIMARY KEY (`id`) 

(我想創建新表,並且從舊錶複製所有數據。)