MySQL Count(*)提速30倍
MySQL InnoDB是索引組織表,如果根據主鍵大範圍查詢,效率非常低下。
因為主鍵索引中還包含資料,需要掃描大量的塊。
這種場景,如果有一個二級索引,則可以極大的提升查詢速度。
初始化實驗資料(100W記錄)
使用主鍵索引的count(*)查詢
使用二級索引的count(*)查詢
使用二級索引相比主鍵索引有近30倍的提升。
但是奇怪的是,按照Oracle對於索引的描述,不全為null的內容可以被索引。
很明顯,t表的num欄位可以為空。
插入一個空值之後,居然還可以使用索引??非常奇怪
包含null值,依然使用索引的count(*)
對空值的查詢居然還能使用索引?
不走索引著急,不明白為什麼走索引也著急。
因為主鍵索引中還包含資料,需要掃描大量的塊。
這種場景,如果有一個二級索引,則可以極大的提升查詢速度。
初始化實驗資料(100W記錄)
-
--建立實驗表
-
create table t(
-
id int primary key,
-
num int,
-
content varchar(1000)
-
)engine=innodb;
-
-
--建立可以產生隨機字串的函式
-
DROP FUNCTION IF EXISTS rand_string;
-
delimiter //
-
CREATE FUNCTION rand_string(l_num int UNSIGNED,l_type tinyint UNSIGNED)
-
RETURNS varchar(2000)
-
BEGIN
-
-- Function : rand_string
-
-- Author : dbachina#dbachina.com
-
-- Date : 2010/5/30
-
-- l_num : The length of random string
-
-- l_type: The string type
-
-- 1.0-9
-
-- 2.a-z
-
-- 3.A-Z
-
-- 4.a-zA-Z
-
-- 5.0-9a-zA-Z
-
--
:
-
-- mysql> select rand_string(12,5) random_string;
-
-- +---------------+
-
-- | random_string |
-
-- +---------------+
-
-- | 3KzGJCUJUplw |
-
-- +---------------+
-
-- 1 row in set (0.00 sec)
-
DECLARE i int UNSIGNED DEFAULT 0;
-
DECLARE v_chars varchar(64) DEFAULT '0123456789';
-
DECLARE result varchar (2000) DEFAULT '';
-
-
IF l_type = 1 THEN
-
SET v_chars = '0123456789';
-
ELSEIF l_type = 2 THEN
-
SET v_chars = 'abcdefghijklmnopqrstuvwxyz';
-
ELSEIF l_type = 3 THEN
-
SET v_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
ELSEIF l_type = 4 THEN
-
SET v_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
ELSEIF l_type = 5 THEN
-
SET v_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
ELSE
-
SET v_chars = '0123456789';
-
END IF;
-
-
WHILE i < l_num DO
-
SET result = concat( result,substr(v_chars,ceil(rand()*(length(v_chars)-1)),1) );
-
SET i = i + 1;
-
END WHILE;
-
RETURN result;
-
END;
-
//
-
delimiter ;
-
-
--插入100W條實驗資料
-
DROP PROCEDURE IF EXISTS insertTableT;
-
delimiter //
-
create procedure insertTableT()
-
begin
-
declare i int;
-
set i=0;
-
while i<1000000 do
-
insert into t values(i,i,rand_string(1000,5));
-
set i=i+1;
-
end while;
-
end;
-
//
- delimiter ;
使用主鍵索引的count(*)查詢
-
mysql> explain select count(*) from t;
-
+----+-------------+-------+-------+---------------+---------+---------+------+--------+-------------+
-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
-
+----+-------------+-------+-------+---------------+---------+---------+------+--------+-------------+
-
| 1 | SIMPLE | t | index | NULL | PRIMARY | 4 | NULL | 931113 | Using index |
-
+----+-------------+-------+-------+---------------+---------+---------+------+--------+-------------+
-
1 row in set (0.00 sec)
-
-
mysql> select count(*) from t;
-
+----------+
-
| count(*) |
-
+----------+
-
| 1000000 |
-
+----------+
- 1 row in set (6.85 sec)
使用二級索引的count(*)查詢
-
mysql> create index t_num on t(num);
-
Query OK, 0 rows affected (9.55 sec)
-
Records: 0 Duplicates: 0 Warnings: 0
-
-
mysql> explain select count(*) from t;
-
+----+-------------+-------+-------+---------------+-------+---------+------+--------+-------------+
-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
-
+----+-------------+-------+-------+---------------+-------+---------+------+--------+-------------+
-
| 1 | SIMPLE | t | index | NULL | t_num | 5 | NULL | 931113 | Using index |
-
+----+-------------+-------+-------+---------------+-------+---------+------+--------+-------------+
-
1 row in set (0.00 sec)
-
-
mysql> select count(*) from t;
-
+----------+
-
| count(*) |
-
+----------+
-
| 1000000 |
-
+----------+
- 1 row in set (0.18 sec)
但是奇怪的是,按照Oracle對於索引的描述,不全為null的內容可以被索引。
很明顯,t表的num欄位可以為空。
插入一個空值之後,居然還可以使用索引??非常奇怪
-
mysql> insert into t(id,num,content) values(1000001,null,'1');
-
Query OK, 1 row affected (0.02 sec)
-
-
mysql> commit;
- Query OK, 0 rows affected (0.04 sec)
-
mysql> explain select count(*) from t;
-
+----+-------------+-------+-------+---------------+-------+---------+------+--------+-------------+
-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
-
+----+-------------+-------+-------+---------------+-------+---------+------+--------+-------------+
-
| 1 | SIMPLE | t | index | NULL | t_num | 5 | NULL | 931114 | Using index |
-
+----+-------------+-------+-------+---------------+-------+---------+------+--------+-------------+
-
1 row in set (0.00 sec)
-
-
mysql> select count(*) from t;
-
+----------+
-
| count(*) |
-
+----------+
-
| 1000001 |
-
+----------+
- 1 row in set (0.18 sec)
- mysql> explain select * from t where num is null;
-
+----+-------------+-------+------+---------------+-------+---------+-------+------+-----------------------+
-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
-
+----+-------------+-------+------+---------------+-------+---------+-------+------+-----------------------+
-
| 1 | SIMPLE | t | ref | t_num | t_num | 5 | const | 1 | Using index condition |
-
+----+-------------+-------+------+---------------+-------+---------+-------+------+-----------------------+
-
1 row in set (0.00 sec)
-
-
mysql> select * from t where num is null;
-
+---------+------+---------+
-
| id | num | content |
-
+---------+------+---------+
-
| 1000001 | NULL | 1 |
-
+---------+------+---------+
- 1 row in set (0.00 sec)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1147227/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL的COUNT語句--count(*)、 count(常量)、 count(列名)MySql
- 如何將 MySQL 查詢速度提升 300 倍MySql
- 圖形加速可令Java提速10倍Java
- mysql中count(1)與count(*)比較MySql
- 【MySQL】效能優化之 count(*) VS count(col)MySql優化
- PostgreSQL隨機記錄返回-300倍提速實踐(隨機陣列下標代替orderbyrandom())SQL隨機陣列random
- 圖解MySQL:count(*) 、count(1) 、count(主鍵欄位)、count(欄位)哪個效能最好?圖解MySql
- MySQL:count(*) count(欄位) 實現上區別MySql
- mysql count()的使用解析MySql
- mysql中count的用法MySql
- 我是如何使計算提速>150倍的
- 提速 Spark SQL 2 倍,GLUTEN 向量化引擎原理剖析SparkSQL
- 一次提速1000倍的delete操作delete
- 使用子查詢可提升 COUNT DISTINCT 速度 50 倍
- 如何用WebAssembly為Web應用提速20倍(案例研究)Web
- [譯] 用 WebAssembly 提速 Web App 20 倍(例項學習)WebAPP
- 如何讓 Xcode 在讀寫上提速100倍?XCode
- MySQL優化COUNT()查詢MySql優化
- MySQL:SELECT COUNT 小結MySql
- mysql count函式說明MySql函式
- 部落格構建效能最佳化筆記 | 提速 3 倍筆記
- 百萬資料 mysql count(*)優化MySql優化
- 立竿見影地把你的 Python 程式碼提速7倍Python
- 【Python】我是如何使計算時間提速25.6倍的Python
- Jeff Dean新提出機器學習索引替代B-Trees:可提速3倍機器學習索引
- (11.28)5到10倍 新型量子金鑰分配系統提速
- MySQL:COUNT(*) profile optimizing階段慢MySql
- MySQL中count(*)函式原理詳解MySql函式
- 為PHP應用提速、提速、再提速!PHP
- count(0),count(1),count(*)總結與count(column)
- 【優化】COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主鍵)、COUNT(ROWID)等優化
- 安裝mysql遇到ERROR: 1136 Column count doesn't match value count at row 1MySqlError
- mysql 1558 - Column count of mysql.proc is wrong 的解決MySql
- count(1),count(*),count(列)的區別
- Mysql報錯注入原理分析(count()、rand()、group by)MySql
- MYSQL count標量子查詢改left joinMySql
- 【案例】MySQL count操作優化案例一則MySql優化
- 新型量子金鑰分配系統提速比現在快5到10倍!