1. 背景介绍
什么是semi-join?
所谓的semi-join是指semi-join子查询。 该子查询具有如下结构:
这种查询的特点是我们只关心outer_table中与semi-join相匹配的记录。
换句话说,最后的结果集是在outer_tables中的,而semi-join的作用只是对outer_tables中的记录进行筛选。这也是我们进行semi-join优化的基础,即我们只需要从semi-join中获取到最少量的足以对outer_tables记录进行筛选的信息就足够了。
所谓的最少量,体现到优化策略上就是如何去重。
以如下语句为例:
我们可以看到这里有2个China,分别来至2条城市记录Beijin和Shanghai, 但实际上我们只需要1个China就足够对outer_table Country进行筛选了。所以我们需要去重。
2. Mysql支持的Semi-join策略
Mysql支持的semi-join策略主要有5个,它们分别为:
1. DuplicateWeedout: 使用临时表对semi-join产生的结果集去重。
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/ac8c9525b73b696af022138b6082bce8.jpeg)
对应的匹配条件为:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/68080714c149c1fabb16a18415db7ef3.jpeg)
2. FirstMatch: 只选用内部表的第1条与外表匹配的记录。
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/2252336f45fe0ba42c2bab23b5b2a257.jpeg)
对应的匹配条件为:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/386258d8942c6ec88e0ef24f6f0c9fb7.jpeg)
3. LooseScan: 把inner-table数据基于索引进行分组,取每组第一条数据进行匹配。
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/81d42b74860a598be694d3c1e113d301.jpeg)
对应的匹配条件为:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/351064ea45fdf71dfbcbd6885cd9a3a8.jpeg)
4. Materializelookup: 将inner-table去重固化成临时表,遍历outer-table,然后在固化表上去寻找匹配。
对应的匹配条件:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/5473a4777485698b49821dbe4712a5f6.jpeg)
5. MaterializeScan: 将inner-table去重固化成临时表,遍历固化表,然后在outer-table上寻找匹配。
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/e697979a24f61c61156b2a6afb42f923.jpeg)
对应的条件:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/ae6e26f014b2b4fb448e40756d32fd39.jpeg)
参考:
1.mysql代码 (sql/sql_select.cc 的setup_semijoin_dups_elimination函数)
什么是semi-join?
所谓的semi-join是指semi-join子查询。 该子查询具有如下结构:
SELECT ... FROM outer_tables WHERE expr IN (SELECT ... FROM inner_tables ...) AND ...
即在where条件的“IN”中的那个子查询。这种查询的特点是我们只关心outer_table中与semi-join相匹配的记录。
换句话说,最后的结果集是在outer_tables中的,而semi-join的作用只是对outer_tables中的记录进行筛选。这也是我们进行semi-join优化的基础,即我们只需要从semi-join中获取到最少量的足以对outer_tables记录进行筛选的信息就足够了。
所谓的最少量,体现到优化策略上就是如何去重。
以如下语句为例:
select * from Country
where Country.Code in
(select City.country from City where City.Population>1*1000*1000);
当中的semi-join: “
select City.country from City where City.Population>1*1000*1000
” 可能返回的结果集如下: China(Beijin), China(Shanghai), France(Paris)...我们可以看到这里有2个China,分别来至2条城市记录Beijin和Shanghai, 但实际上我们只需要1个China就足够对outer_table
2. Mysql支持的Semi-join策略
Mysql支持的semi-join策略主要有5个,它们分别为:
1. DuplicateWeedout: 使用临时表对semi-join产生的结果集去重。
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/ac8c9525b73b696af022138b6082bce8.jpeg)
对应的匹配条件为:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/68080714c149c1fabb16a18415db7ef3.jpeg)
2. FirstMatch: 只选用内部表的第1条与外表匹配的记录。
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/2252336f45fe0ba42c2bab23b5b2a257.jpeg)
对应的匹配条件为:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/386258d8942c6ec88e0ef24f6f0c9fb7.jpeg)
3. LooseScan: 把inner-table数据基于索引进行分组,取每组第一条数据进行匹配。
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/81d42b74860a598be694d3c1e113d301.jpeg)
对应的匹配条件为:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/351064ea45fdf71dfbcbd6885cd9a3a8.jpeg)
4. Materializelookup: 将inner-table去重固化成临时表,遍历outer-table,然后在固化表上去寻找匹配。
对应的匹配条件:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/5473a4777485698b49821dbe4712a5f6.jpeg)
5. MaterializeScan: 将inner-table去重固化成临时表,遍历固化表,然后在outer-table上寻找匹配。
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/e697979a24f61c61156b2a6afb42f923.jpeg)
对应的条件:
![mysql中semi-join的优化策略介绍 mysql中semi-join的优化策略介绍](https://i-blog.csdnimg.cn/blog_migrate/ae6e26f014b2b4fb448e40756d32fd39.jpeg)
参考:
1.mysql代码 (sql/sql_select.cc 的setup_semijoin_dups_elimination函数)
2.askmonty的knowledgebase
from : http://blog.sina.com.cn/s/blog_4673e60301011qvx.html