筆者如今遇到這麼一個場景,sql
一個單表中包含有6000w+的數據,然而你又不能拆分.須要分別統計表中有多少數據,A產品有多少,B產品有多少這幾個數據.優化
在爲優化以前.表結構以下,爲了隱藏內容我將相應字段作了模糊化處理.設計
CREATE TABLE `xxxx` ( `link` varchar(200) DEFAULT NULL, `test0` varchar(500) DEFAULT NULL, `test1` varchar(50) DEFAULT NULL, `test2` int(11) DEFAULT NULL, `test3` varchar(20) DEFAULT NULL, `test4` varchar(50) DEFAULT NULL, `test5` varchar(50) NOT NULL, `inserttime` datetime DEFAULT NULL, `test6` bit(1) NOT NULL DEFAULT b'0', `A` bit(1) NOT NULL DEFAULT b'0', `B` bit(1) NOT NULL DEFAULT b'0' , PRIMARY KEY (`test5`), KEY `test6` (`test6`) USING BTREE, KEY `A` (`A`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這個一個常規的InnoDB
的表格,因此它的count(*)
比起MyISAM
的效率慢不少,InnoDB
所顯示的row
的行數不很準確,因此在這這裏我須要統計一下.有這麼幾個策略.
共計61500000數據code
count(*)
耗時 1539.499scount(1)
耗時 907.581scount(A)
對索引進行count.count(test6)
對主鍵進行count.無一例外,因爲這個表沒有優化好上面不管哪種都須要幾千秒的時間,這個是咱們沒法忍受的.索引
下面咱們開始着手分析處理這個問題.字符串
預期整個表的count(*)
應該在200s之內爲正常,100之內爲良好,50之內爲優秀.產品
首先我將裏面test6
抽取了出來,單獨造成了一個表.對其進行操做.
共計61500000數據it
count(*)
耗時10.238scount(1)
耗時8.710scount(test6)
對主鍵進行count.耗時12.957s其中count(1)
的效率最高,比最慢count(pk)
速度提高了52.0%.class
將你能肯定的字段改成最優值,例如:test
varchar
更爲char
.雖然varchar
能夠自動分配存儲空間的大小可是.varchar
須要使用1到2個額外的字節來記錄字符串的長度,增長它的update
的操做時間,datetime
改成timestamp
後者在1978-2038年之間 最後使用count(1)
檢驗的時候最快耗時,168s.雖然有些慢可是能夠接受.
總結:
varchar
.count(1)
而不是count(*)
來檢索.