semi-join子查詢優化 -- LooseScan策略

LooseScan執行semi-join子查詢的一種策略。sql

咱們將經過示例來演示這種鬆散(LooseScan)策略。
假設,咱們正在查找擁有衛星的國家。咱們能夠經過如下查詢得到它們(爲了簡單起見,咱們忽略了多個國家財團擁有的衛星):spa

select * from Country  
where 
  Country.code in (select country_code from Satellite);

  

假設,在Satellite.country_code上有一個索引。若是咱們使用該索引,咱們將按衛星所屬國家的順序獲得衛星:code

 

LooseScan策略其實並不真的須要排序,真正須要的是分組。在上面的圖中,衛星是根據國家分組的。例如,澳大利亞(AUS)全部的衛星在一塊兒。這就很便於從一組中找出一個衛星,將其對應的國家進行鏈接,得到一個國家列表,且沒有重複的國家記錄:blog

 

上面的查詢使用LooseScan以後,執行計劃相似以下:排序

MariaDB [world]> explain select * from Country where Country.code in (select country_code from Satellite);
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+
| id | select_type | table     | type   | possible_keys | key          | key_len | ref                          | rows | Extra                               |
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+
|  1 | PRIMARY     | Satellite | index  | country_code  | country_code | 9       | NULL                         |  932 | Using where; Using index; LooseScan |
|  1 | PRIMARY     | Country   | eq_ref | PRIMARY       | PRIMARY      | 3       | world.Satellite.country_code |    1 | Using index condition               |
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+

  

·LooseScan避免了產生重複的記錄,經過將子查詢表放在首位並使用其索引去從多個重複記錄中選擇一條記錄。
所以,要想使用LooseScan,子查詢應該看起來像下面的例子:索引

expr IN (SELECT tbl.keypart1 FROM tbl ...)

orget

expr IN (SELECT tbl.keypart2 FROM tbl WHERE tbl.keypart1=const AND ...)

·LooseScan支持相關子查詢
·是否開啓LooseScan是由系統變量optimizer_switch中的loosescan=on|off設置的。it

 

https://mariadb.com/kb/en/library/loosescan-strategy/io

相關文章
相關標籤/搜索