explain select * from ecs_ad where ad_id =1 or ad_id = 3;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
| 1 | SIMPLE | ecs_ad | range | PRIMARY | PRIMARY | 2 | NULL | 2 | Using index condition |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
1 row in set
這是union all的
explain select * from ecs_ad where ad_id = 4 union all select * from ecs_ad where ad_id = 3;
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
| 1 | PRIMARY | ecs_ad | const | PRIMARY | PRIMARY | 2 | const | 1 | NULL |
| 2 | UNION | ecs_ad | const | PRIMARY | PRIMARY | 2 | const | 1 | NULL |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
3 rows in set
首先,這兩個查詢效能差距應該不大。
因為 ad_id 欄位是主鍵.
根據 type 欄位分析:
or 查詢,
type:range
type:range
union all 查询:
type:const / const / ALL
union all 查詢:type:const / const / ALL
首先可以確認的是,
const
要優於range
.const
要优于range
.const
const
也是因為 ad_id 為主鍵.但是 union all 做了三次操作,兩次主鍵或唯一索引查詢 type:const,但最後組合到一起時 type:ALL
type:ALL 本身性能比 range 還要差
從 Type 看,or 查詢效能應該更好.
Extra 分析
or 查詢:
Using index condition
Using index condition
union all 查询:
NULL / NULL / Using temporary
union all 查詢:NULL / NULL / Using temporary
Using index condition 為 MySQL 5.6 版本以後新加入的特性,索引條件推送。
先說一下沒有索引條件推送時候的處理流程:
當存在索引條件推播時候的處理流程:
簡單來說,沒有 ICP 時,儲存引擎會傳回所有滿足條件的整行數據,在 service 層進行 where 條件過濾。
有 ICP 時,where 條件下推到儲存引擎層,儲存引擎直接傳回符合條件的資料。
性能自然提高很多。
對於 ICP 的相關介紹,可以查看這裡
而 Using temporary 表示隱式臨時表,意思是 MySQL 會在產生一個臨時表,存放中間資料。因為 union all 是分開處理,最後合併的關係。
從 Extra 看,也應該是 or 查詢效能更高。
綜合來看:OR 查詢的效能應該有優於 UNION ALL .
由於所有查詢效能都隨著資料量增加而變化,以上分析只是單看題主所貼的 Explain 分析結果。也並不是說 OR 在所有情況下都優於 UNION ALL。
以上為個人意見,如有錯誤,請指正。
這兩個語句,無差別。
一般or連接兩個不同字段,無法使用索引的時候,效能會比較差,不如union,可以嘗試修改。