MySQL_列值為null對索引的影響_實踐
阿新 • • 發佈:2018-11-05
一.首先看一個我在某公眾號看到的一個關於資料庫優化的舉措
二.如果where子句中查詢的列執行了 “is null” 或者 “is not null” 或者 “<=> null” 會不會使用索引呢?
先列出結論:where子句中使用上述對null的判斷,如果判斷的列設定了索引,那就可以使用到索引
官方依據在:https://dev.mysql.com/doc/refman/5.6/en/is-null-optimization.html
三.測試:
1.建表
1 CREATE TABLE `test_null_index` (2 `id` int(11) DEFAULT NULL, 3 `mark` varchar(20) DEFAULT NULL, 4 `name` varchar(11) DEFAULT NULL 5 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.插資料
create procedure test_null_index(in num int) BEGIN DECLARE i int; set i=1; while (i<num) DO if mod(i,10)!=0 then insert intotest_null_index values (i,concat('aaa',i),null); else insert into test_null_index values (null,concat('aaa',i),'bbb'); end if; set i=i+1; END while; END; call test_null_index(10000);
3.沒加索引時,type為All,全表掃描
mysql> explain SELECT * from test_null_index WHERE id is null; +----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+ | 1 | SIMPLE | test_null_index | ALL | NULL | NULL | NULL | NULL | 10589 | Using where | +----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+ 1 row in set (0.00 sec)
4.加上索引,可以看到,索引起作用了
mysql> create index idx_test_null on test_null_index(id); Query OK, 0 rows affected (0.12 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> explain SELECT * from test_null_index WHERE id is null; +----+-------------+-----------------+------+---------------+---------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------+------+---------------+---------------+---------+-------+------+-------------+ | 1 | SIMPLE | test_null_index | ref | idx_test_null | idx_test_null | 5 | const | 998 | Using where | +----+-------------+-----------------+------+---------------+---------------+---------+-------+------+-------------+ 1 row in set (0.00 sec)
四.注意,只能使用針對一個欄位的關於null的判斷,如果同時在兩個欄位對null進行判斷,還是會走全表掃描
1.測試,可以看到,在name欄位加上索引,並查詢name為空的語句,同樣會走索引
mysql> create index idx_test_null2 on test_null_index(name); Query OK, 0 rows affected (0.13 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> explain SELECT * from test_null_index WHERE name is null; +----+-------------+-----------------+------+----------------+----------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------+------+----------------+----------------+---------+-------+------+-------------+ | 1 | SIMPLE | test_null_index | ref | idx_test_null2 | idx_test_null2 | 36 | const | 8994 | Using where | +----+-------------+-----------------+------+----------------+----------------+---------+-------+------+-------------+ 1 row in set (0.00 sec)
2.同時針對id和name查詢為空的語句,走的是全表掃描
mysql> explain SELECT * from test_null_index WHERE id is null or name is null; +----+-------------+-----------------+------+------------------------------+------+---------+------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------+------+------------------------------+------+---------+------+-------+-------------+ | 1 | SIMPLE | test_null_index | ALL | idx_test_null,idx_test_null2 | NULL | NULL | NULL | 10589 | Using where | +----+-------------+-----------------+------+------------------------------+------+---------+------+-------+-------------+ 1 row in set (0.01 sec)