Losse_scan/松散扫描:在执行连接的时候,半连接的表S (R semi-join S)其元组需要有序(a in select b from t,b 上存在索引,其元组的顺序按照b成分组状,则使用b上可用的索引读取元组的时候,可以按序引序把相同的值的元组有序读到),此时,根据索引拿出每组重复元组中的第一个元组(其他重复元组被读到后跳过,所以要求S的元组有序),与R表进行连接。[LosseScan:使用索引扫描,基于索引进行分组只取分组的第一条记录与外部表进行匹配;在EXPLAIN的extra字段显示LooseScan(m,n)]
select * from Country
where
Country.code in (select country_code from Satellite)
假设在Satellite.country_code上有一个索引。
LooseScan策略并不需要排序,它需要的是分组。 在上图中,卫星按国家分组。 并获得没有重复的国家列表:
[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 ...)
expr IN (SELECT tbl.keypart2 FROM tbl WHERE tbl.keypart1=const AND ...)
LooseScan可以处理相关的子查询
LooseScan可以通过设置optimizer_switch变量中的loosescan = off标志来关闭。