MySQL中的semi-join
https://www.linuxidc.com/Linux/2015-05/117523.htm
1. 背景介绍
什么是semi-join?
所谓的semi-join是指semi-join子查询。 当一张表在另一张表找到匹配的记录之后,半连接(semi-jion)返回第一张表中的记录。与条件连接相反,即使在右节点中找到几条匹配的记录,左节点 的表也只会返回一条记录。另外,右节点的表一条记录也不会返回。半连接通常使用IN 或 EXISTS 作为连接条件。 该子查询具有如下结构:
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产生的结果集去重。
![](https://www.linuxidc.com/upload/2015_05/150514191046041.png)
对应的匹配条件为:
![](https://www.linuxidc.com/upload/2015_05/150514191046042.png)
2. FirstMatch: 只选用内部表的第1条与外表匹配的记录。
![](https://www.linuxidc.com/upload/2015_05/150514191046043.png)
对应的匹配条件为:
![](https://www.linuxidc.com/upload/2015_05/150514191046044.png)
3. LooseScan: 把inner-table数据基于索引进行分组,取每组第一条数据进行匹配。
![](https://www.linuxidc.com/upload/2015_05/150514191046045.jpg)
对应的匹配条件为:
![](https://www.linuxidc.com/upload/2015_05/150514191046046.jpg)
4. Materializelookup: 将inner-table去重固化成临时表,遍历outer-table,然后在固化表上去寻找匹配。
对应的匹配条件:
![](https://www.linuxidc.com/upload/2015_05/150514191046047.png)
5. MaterializeScan: 将inner-table去重固化成临时表,遍历固化表,然后在outer-table上寻找匹配。
对应的条件:
optimizer_switch
system variable. The semijoin
flag controls whether semi-joins are used. If it is set to on
, the firstmatch
, loosescan
, and materialization
flags enable finer control over the permitted semi-join strategies. These flags are on
by default.
The use of semi-join strategies is indicated in EXPLAIN
output as follows:
Semi-joined tables show up in the outer select.
EXPLAIN EXTENDED
plusSHOW WARNINGS
shows the rewritten query, which displays the semi-join structure. From this you can get an idea about which tables were pulled out of the semi-join. If a subquery was converted to a semi-join, you will see that the subquery predicate is gone and its tables andWHERE
clause were merged into the outer query join list andWHERE
clause.Temporary table use for Duplicate Weedout is indicated by
Start temporary
andEnd temporary
in theExtra
column. Tables that were not pulled out and are in the range ofEXPLAIN
output rows covered byStart temporary
andEnd temporary
will have theirrowid
in the temporary table.FirstMatch(
tbl_name) in theExtra
column indicates join shortcutting.LooseScan(
m..n
) in theExtra
column indicates use of the LooseScan strategy.m
andn
are key part numbers.
As of MySQL 5.6.7, temporary table use for materialization is indicated by rows with a
select_type
value ofMATERIALIZED
and rows with atable
value of<subquery
N>.Before MySQL 5.6.7, temporary table use for materialization is indicated in the
Extra
column byMaterialize
if a single table is used, or byStart materialize
andEnd materialize
if multiple tables are used. IfScan
is present, no temporary table index is used for table reads. Otherwise, an index lookup is used.
mysql> SELECT @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,
index_merge_sort_union=on,
index_merge_intersection=on,
engine_condition_pushdown=on,
index_condition_pushdown=on,
mrr=on,mrr_cost_based=on,
block_nested_loop=on,batched_key_access=off,
materialization=on,semijoin=on,loosescan=on,
firstmatch=on,
subquery_materialization_cost_based=on,
use_index_extensions=on
本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-05/117523.htm
MySQL中的semi-join相关推荐
- Hive中HSQL中left semi join
Hive中HSQL中left semi join 证明在Hive 2.1.1版本中,是支持where子句中的子查询,SQL常用的exist in子句在Hive中是不支持的,但可以使用一个更高效的实现方 ...
- mysql left outer join_关于mysql中的left join和left outer join的区别
关于mysql中的left join和left outer join的区别 LEFT JOIN是LEFT OUTER JOIN的简写版; 内连接(INNER JOIN) :只连接匹配的行; 左外连接( ...
- Mysql中WhereIn和Join的性能比对
在mysql中使用whereIn和Join表性能区别, 在查询多表的关系的时候,存在两种查询方法. 一种是找出对应关系的ID,然后根据对应关系的ID的集合,到目标表中查询出结果. 另外一种,是联立两张 ...
- mysql中的各种join整理
Join可以分为两种 ①implicit join ②explicit join 举例如下: 类型 SQL举例 explicit join SELECT * FROM A a JOIN B b ON ...
- mysql中distinct与join,INNER JOIN DISTINCT与MySQL
我有一个mysql问题.我有两张这样的桌子需要一起加入. 表: id otherid2 1 | 1 2 | 1 3 | 2 4 | 2 表2: otherid otherid2 1 | 1 2 | 1 ...
- mysql inner和left优化_浅谈mysql中的left join和inner join性能及优化策略
前言 看一下 下面的sql语句:select * from a left join b on a.x = b.x left join c on c.y = b.y 这样的多个left join组合的时 ...
- 学习mysql中使用inner join,left join 等
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 inner join(等值连接) ...
- MySQL中的LEFT JOIN ON (where)查询
LEFT JOIN ON的使用语法: select [需要查询的字段] from [table_name1] left join [table_name2] on [两个表关联的条件] (where ...
- MySql中为什么LEFT JOIN执行的速度更快,而说是INNER JOIN效率高。
毫无疑问的是使用left join 时系统做的逻辑运算量大于inner join,是因为inner join 只需选出能匹配的记录,left join 不仅需要选出能匹配的,而且还要返回左表不能匹配的 ...
- mysql中的left join用法 (及多条件查询
语法:FROM table1 LEFT JOIN table2 ON table1.field1 compopr table2.field2 说明:table1, table2参数用于指定要将记录组 ...
最新文章
- 学习java技术有前途吗
- 【每日一算法】填充同一层的兄弟节点
- 工作10年从大公司离职去小公司当CTO,被同事鄙视竟然不回netty
- 论文笔记 DNorm: disease name normalization with pairwise learning to rank
- python批量读取文件夹中的所有excel文件-python遍历文件夹下所有excel文件
- 算法练习——ACM_1001_Exponentiation
- ABAP 如何实现屏幕字段不可输入
- 数学之美系列12(转帖)
- CF1497E2 Square-free division (hard version)
- php算次方,php怎么计算几次方
- 牛客网-这是一个沙雕题
- 俄罗斯方块游戏设计的有关问题
- 终端SSH工具SecureCRT 9.2.0 for Mac
- Dota2 AI开发(一)环境配置
- Qt之Cannot retrieve debugging output.
- 分布式文件系统(DFS)浅析
- ppt密码忘了怎么解除,ppt权限密码怎么解开?
- 李小杰_测试工程师简历
- LaTeX 公式左对齐与右对齐
- EF实体类种的Virtual关键字作用