测试前准备:
一:简单的用户表(username列加索引测试):
CREATE TABLE `test_count` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`phone` varchar(11) DEFAULT NULL,
`nick_name` varchar(50) DEFAULT NULL,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`gender` tinyint(1) DEFAULT NULL,
`is_del` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=17805 DEFAULT CHARSET=utf8;
二:模拟数据插入前准备(插入一样的数据也行,但为了模拟数据的真实性,全部插入了随机数据,保证与真实数据具有相同的可比性):
1.创建随机字符串函数
DROP FUNCTION IF EXISTS getRandomStr;
delimiter $
CREATE FUNCTION getRandomStr(num INT) RETURNS VARCHAR(100)
BEGIN
DECLARE str VARCHAR(36) DEFAULT 'abcdefghijklmnopqrstuvwxyz0123456789';
DECLARE rstr VARCHAR(100) DEFAULT '';
DECLARE i INT DEFAULT 0;
DECLARE n INT DEFAULT 0;
a:WHILE i<num DO
SELECT FLOOR(1+RAND() * 36) INTO n;
SELECT CONCAT(rstr,SUBSTR(str,n,1)) INTO rstr;
SET i=i+1;
END WHILE a;
RETURN rstr;
END $
delimiter ;
2.随机手机号函数
DROP FUNCTION IF EXISTS getRandomPhone;
delimiter $
CREATE FUNCTION getRandomPhone() RETURNS VARCHAR(11)
BEGIN
DECLARE str VARCHAR(10) DEFAULT '0123456789';
DECLARE num INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE restr VARCHAR(11) DEFAULT '1';
a:WHILE i < 10 DO
SELECT FLOOR(RAND()*10+1) INTO num;
SELECT CONCAT(restr,SUBSTR(str,num,1)) INTO restr;
SET i = i + 1;
END WHILE a;
RETURN restr;
END $
delimiter ;
3.随机0或者1函数
DROP FUNCTION IF EXISTS getRandomSex;
delimiter $
CREATE FUNCTION getRandomSex() RETURNS INT
BEGIN
DECLARE n INT DEFAULT 0;
SET n = FLOOR(RAND()*2);
RETURN n;
END $
delimiter ;
DROP FUNCTION IF EXISTS getRandomSex;
delimiter $
CREATE FUNCTION getRandomSex() RETURNS INT
BEGIN
DECLARE n INT DEFAULT 0;
SET n = FLOOR(RAND()*2);
RETURN n;
END $
delimiter ;
4.创建存储过程,批量插入模拟数据(建议关闭mysql日志,否则异常慢)
DROP PROCEDURE IF EXISTS cp_it;
delimiter $
CREATE PROCEDURE cp_it(IN num INT)
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit=0;
a:WHILE i<num DO
INSERT INTO test_count(phone,nick_name,username,`password`,gender,is_del) VALUES (getRandomPhone(),getRandomStr(8),getRandomStr(25),getRandomStr(32),getRandomSex(),getRandomSex());
IF MOD(i,500)=0 THEN COMMIT;
END IF;
SET i = i+1;
END WHILE a;
END $
delimiter ;
5.关闭mysql查询缓存(这一点很重要,否则影响测试结果准确性)
SELECT @@query_cache_type;
set global query_cache_type=0;
三:测试阶段
1.插入50000条数据测试
CALL cp_it(50000);
第一次测试结果
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.012ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.012ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.011ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.011ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.013ms
第二次测试结果
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.011ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.009ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.010ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.012ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.013ms
第三次测试结果
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.010ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.009ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.010ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.012ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.014ms
第四次测试结果
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.009ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.009ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.011ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.011ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.013ms
第五次测试结果
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.009ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.009ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.010ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.012ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.014ms
5w条数据看不出明显差距
2.10W条数据测试
第一次
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.020ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.018ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.019ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.023ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.025ms
第二次
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.019ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.018ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.019ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.024ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.026ms
第三次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.020ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.019ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.020ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.022ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.023ms
第四次
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.022ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.019ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.021ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.023ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.026ms
第五次
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.019ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.019ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.019ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.022ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.025ms
10W条数据差距仍然不明显
3.20W条数据测试
第一次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.036ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.037ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.040ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.045ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.049ms
第二次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.040ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.037ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.039ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.043ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.052ms
第三次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.038ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.037ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.044ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.049ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.054ms
第四次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.038ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.038ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.039ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.044ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.053ms
第五次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.037ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.036ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.040ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.044ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.050ms
20W测试数据下差距开始显现,count(column)明显慢于count(*),count(id)和count(1)
4.50W条数据下的表现:
第一次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.091ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.089ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.097ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.105ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.118ms
第二次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.090ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.087ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.095ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.108ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.120ms
第三次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.091ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.089ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.094ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.111ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.122ms
第四次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.106ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.096ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.097ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.105ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.117ms
第五次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.090ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.088ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.097ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.113ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.121ms
5. 100W条数据下的表现:
鉴于上面方式插入数据太慢,顾采用insert select方法从本表复制插入数据
SET autocommit=0;
INSERT INTO test_count(phone,nick_name,username,`password`,gender,is_del) SELECT phone,nick_name,username,`password`,gender,is_del FROM test_count WHERE id<=500000;
COMMIT;
第一次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.178ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.174ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.187ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.212ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.239ms
第二次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.177ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.176ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.185ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.217ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.239ms
第三次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.176ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.169ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.202ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.211ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.245ms
第四次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.179ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.175ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.185ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.209ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.241ms
第五次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.178ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.175ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.186ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.208ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.241ms
在100W数据下,差距明显拉大,count(*)和count(1),count(id)效率明显大于count(column),带索引的count(column)明显效率高于不带索引的,count(*)和count(1) 差距微乎其微,count(1)稍微大于count(*),但两者效率大于count(id)
6.200W数据下的效率表现:
第一次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.347ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.340ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.361ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.413ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.453ms
第二次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.348ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.336ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.362ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.408ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.465ms
第三次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.350ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.339ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.362ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.410ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.475ms
第四次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.345ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.343ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.361ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.408ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.464ms
第五次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.338ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.340ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.360ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.409ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 0.463ms
count(*)和count(1)的效率明显高于count(id),count(1)的效率稍微高于count(*)但差距仍然不是很明显
7.500W数据下的表现:
第一次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.828ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.827ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.873ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.981ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 7.673ms
明显看出,在500W数据下不加索引的count(column)已经爆炸,特别慢
第二次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.826ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.824ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.880ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 0.987ms
[SQL]
SELECT COUNT(nick_name) FROM test_count;
受影响的行: 0
时间: 7.647ms
第三次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.841ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.831ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.890ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 1.008ms
第四次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.847ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.836ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.900ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 1.008ms
第五次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.839ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.834ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.888ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 1.013ms
第六次:
[SQL] SELECT COUNT(*) FROM test_count;
受影响的行: 0
时间: 0.831ms
[SQL]
SELECT COUNT(1) FROM test_count;
受影响的行: 0
时间: 0.827ms
[SQL]
SELECT COUNT(id) FROM test_count;
受影响的行: 0
时间: 0.878ms
[SQL]
SELECT COUNT(username) FROM test_count;
受影响的行: 0
时间: 1.003ms
由此可以看出 count(1)效率稍微高于count(*),但差距微乎其微
count(1)>count(*)>count(id)>count(column)
1000W的数据就不测了