測試前準備:
一:簡單的用戶表(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的數據就不測了