笔者如今遇到这么一个场景,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(*)
来检索.