機智的MySQL優化器 --- is null

介紹mysql

  工做的越久越到的的問題越多,就越是以爲一些「老話」歷久彌新;因爲最近的學習計劃是深刻的學習一遍MySQL優化器;學習過程當中的一些成果sql

  也會發布到這裏,一來是爲了整理本身已經知道的和新學到的,二來是爲了給本身的網站作個友情鏈接數據庫

 

is null 優化學習

  若是咱們在定義表的時候就給不能爲null的列加上not null 那麼就將是一個很是好的實踐,想一想若是接下來有查詢要查找col is null的話,由於mysql測試

  已經知道col不可能爲null 因此MySQL會直接把這個優化掉,返回空結果集;理由是根本不會存在col is null的行優化

 

看一下is null 有多吊吧網站

  第一步:創建一個測試表spa

create table t(id int not null auto_increment primary key, x int not null,y int);

create index idx_t_x on t(x); -- x 是not null 的

create index idx_t_y on t(y); -- y 是能夠爲空的

insert into t(x,y) values(1,null),(2,2),(3,3);

  第二步:觀察MySQL針對null 和 not null的列的處理是有本質區別的code

explain select x from t where x is null;                                                                    
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra            |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | Impossible WHERE |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
1 row in set, 1 warning (0.00 sec)

  因爲x 不可能爲空,因此當查詢條件是x is null的狀況下MySQL不用去查就直接返回了空結果集,正確+省事blog

mysql> explain select x from t where y is null;
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key     | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | t     | NULL       | ref  | idx_t_y       | idx_t_y | 5       | const |    1 |   100.00 | Using index condition |
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

  因爲y是能夠爲null的、因此表的訪問過程就變成了先讀索引再回表(ref),就算y中的每一行都有值,其過程仍是要比上面的x is null的查詢要多作很多

 

  第三步:無論列上有沒有索引只要表定義中指定了條件不爲null那麼針對is null查詢仍是能夠獲得優化

alter table t add column z int;

explain select x from t where z is null;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | t     | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

  因爲z上沒有索引也沒有定義成 not null 因此針對 z is null只能直接全表掃描、下面看一下定義了not null的狀況

alter table t drop column z;

alter table t add column z int not null; -- 在這種沒有指定默認值的狀況下、int類型默認爲0
explain select * from t where z is null;                                                                    
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra            |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | Impossible WHERE |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
1 row in set, 1 warning (0.00 sec)

 

總結

  not null 應該算是關係模板中域完整性的一部分吧,這個已是關係型數據庫中的一部分;在定義表的時候就應該儘量的把完整性加進去,這樣優化

  器獲得的信息更多,作出的選擇也更加機智。

 

【個人個站點】

  www.sqlpy.com

 

---

相關文章
相關標籤/搜索