MySQL特異功能之:Impossible WHERE noticed after reading const tables

yantaicuiwei發表於2011-06-08

MySQL特異功能之:Impossible WHERE noticed after reading const tables

MySQL 2006-10-01 23:40:35 閱讀2173 評論1  字號: 

用EXPLAIN看MySQL的執行計劃時經常會看到Impossible WHERE noticed after reading const tables這句話,意思是說MySQL透過讀取“const tables”,發現這個查詢是不可能有結果輸出的。比如對下面的表和資料:
  create table t (a int primary key, b int) engine = innodb;
insert into t values(1, 1);
insert into t values(3, 1);
執行“EXPLAIN select * from t where a = 2”時就會輸出“Impossible WHERE noticed after reading const tables”。

不明白所謂的“const tables”是什麼意思,對MySQL在查詢最佳化時竟然可以發現一個查詢不可能輸出結果更是感覺不可思議。按資料庫中“傳統”的做法,查詢最佳化時只會訪問模式定義和統計資訊,而據我所知,資料庫中使用的各種統計資訊如EquiDepth、MaxDiff柱狀圖,MCV,屬性的最大值、最小值等都不可能精確到能夠斷言在上述的表中不存在“a = 2”的記錄。

今天看MySQL Internal手冊時才總算弄明白,原來MySQL並沒有什麼神奇之處,這個Impossible WHERE noticed after reading const tables的結論並不是透過統計資訊做出的,而是真的去實際訪問了一遍資料後,發現確實沒有“a = 2”的行才得出的。

當查詢中對某個表指定了主鍵或非空唯一索引上的等值條件,從而使得最多隻可能產生一條命中結果(只對該表而言)時,MySQL在EXPLAIN之前會優先根據這一條件查詢出對應的記錄,並用記錄的實際值替換查詢中所有用到來自該表的屬性的地方。一個更復雜的例子如下:
  explain select * from t as t1, t as t2 where t1.a = 1 and t2.a = t1.b + 1;

的輸出結果為(由於排版關係省略了一些輸出內容):
+----+...+-----------------------------------------------------+
| id | ... | Extra |
+----+...+-----------------------------------------------------+
| 1 | ... | Impossible WHERE noticed after reading const tables |
+----+...+-----------------------------------------------------+

MySQL得出上述查詢不會輸出結果的步驟如下:
1、首先根據t1.a = 1條件找到一條記錄(1,1);
2、將上述記錄中b的值1替換查詢中的t1.b,即將上述查詢轉化為等價的“explain select 1, 1,t2.a, t2.b from t as t2 where t2.a = 1 + 1”;
3、最佳化器計算常量表示式的值,即計算1+1得出結果為2;
4、最佳化器根據t2.a = 2條件查詢,發現沒有命中記錄;
5、最佳化器最終打斷出上述查詢不可能輸出結果。


說白了,這個“Impossible WHERE noticed after reading const tables”就不再神秘了。但從這件事,我更加感覺到MySQL是個“怪怪”的資料庫,有很多地方跟慣常的做法不太一樣。很多資料庫會在聯接時將指定了唯一索引等值條件的表優先執行,作為查詢執行的第一步,但據我所知只有MySQL將這一步驟提前到查詢最佳化的第一步來做。這麼做到底在什麼情況下才有好處好像是個很微妙的問題,對於本文中給出的這兩個例子,在最佳化時還是執行時做這一步開銷都沒什麼區別。不過這麼做好像沒什麼壞處。

這麼會導致一個“怪怪”的現象,那就是EXPLAIN有時候也會被阻塞。比如“EXPLAIN select * from t where a = 2 lock in share mode”,同時又有另一個事務插入了一條a = 2的記錄而沒有提交時,EXPLAIN就會在那裡等鎖。
從別人那裡複製過來滴

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21601207/viewspace-697437/,如需轉載,請註明出處,否則將追究法律責任。

相關文章