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

Country进行筛选了。所以我们需要去重。

2. Mysql支持的Semi-join策略
Mysql支持的semi-join策略主要有5个,它们分别为:
1. DuplicateWeedout: 使用临时表对semi-join产生的结果集去重。

Duplicate Weedout: Run the semi-join as if it was a join and remove duplicate records using a temporary table.

对应的匹配条件为:

2. FirstMatch: 只选用内部表的第1条与外表匹配的记录。

FirstMatch: When scanning the inner tables for row combinations and there are multiple instances of a given value group, choose one rather than returning them all. This "shortcuts" scanning and eliminates production of unnecessary rows.

对应的匹配条件为:

3. LooseScan: 把inner-table数据基于索引进行分组,取每组第一条数据进行匹配。

LooseScan: Scan a subquery table using an index that enables a single value to be chosen from each subquery's value group.

对应的匹配条件为:

4. Materializelookup: 将inner-table去重固化成临时表,遍历outer-table,然后在固化表上去寻找匹配。
Materialize the subquery into a temporary table with an index and use the temporary table to perform a join. The index is used to remove duplicates. The index might also be used later for lookups when joining the temporary table with the outer tables; if not, the table is scanned.
对应的匹配条件:

5. MaterializeScan: 将inner-table去重固化成临时表,遍历固化表,然后在outer-table上寻找匹配。

对应的条件:

Each of these strategies except Duplicate Weedout can be enabled or disabled using the  optimizer_switch system variable. The  semijoin flag controls whether semi-joins are used. If it is set to  on, the  firstmatchloosescan, and  materializationflags 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 plus SHOW 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 and WHERE clause were merged into the outer query join list and WHERE clause.

  • Temporary table use for Duplicate Weedout is indicated by Start temporary and End temporary in the Extra column. Tables that were not pulled out and are in the range of EXPLAIN output rows covered by Start temporary and End temporary will have their rowid in the temporary table.

  • FirstMatch(tbl_name) in the Extra column indicates join shortcutting.

  • LooseScan(m..n) in the Extra column indicates use of the LooseScan strategy. m and n are key part numbers.

  • As of MySQL 5.6.7, temporary table use for materialization is indicated by rows with a select_type value of MATERIALIZED and rows with a table value of <subqueryN>.

    Before MySQL 5.6.7, temporary table use for materialization is indicated in the Extra column by Materialize if a single table is used, or by Start materialize and End materialize if multiple tables are used. If Scan 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相关推荐

  1. Hive中HSQL中left semi join

    Hive中HSQL中left semi join 证明在Hive 2.1.1版本中,是支持where子句中的子查询,SQL常用的exist in子句在Hive中是不支持的,但可以使用一个更高效的实现方 ...

  2. mysql left outer join_关于mysql中的left join和left outer join的区别

    关于mysql中的left join和left outer join的区别 LEFT JOIN是LEFT OUTER JOIN的简写版; 内连接(INNER JOIN) :只连接匹配的行; 左外连接( ...

  3. Mysql中WhereIn和Join的性能比对

    在mysql中使用whereIn和Join表性能区别, 在查询多表的关系的时候,存在两种查询方法. 一种是找出对应关系的ID,然后根据对应关系的ID的集合,到目标表中查询出结果. 另外一种,是联立两张 ...

  4. mysql中的各种join整理

    Join可以分为两种 ①implicit join ②explicit join 举例如下: 类型 SQL举例 explicit join SELECT * FROM A a JOIN B b ON ...

  5. 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 ...

  6. 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组合的时 ...

  7. 学习mysql中使用inner join,left join 等

    left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录  right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 inner join(等值连接) ...

  8. MySQL中的LEFT JOIN ON (where)查询

    LEFT JOIN ON的使用语法: select [需要查询的字段] from [table_name1] left join [table_name2] on [两个表关联的条件] (where ...

  9. MySql中为什么LEFT JOIN执行的速度更快,而说是INNER JOIN效率高。

    毫无疑问的是使用left join 时系统做的逻辑运算量大于inner join,是因为inner join 只需选出能匹配的记录,left join 不仅需要选出能匹配的,而且还要返回左表不能匹配的 ...

  10. mysql中的left join用法 (及多条件查询

    语法:FROM table1 LEFT JOIN table2 ON table1.field1 compopr table2.field2  说明:table1, table2参数用于指定要将记录组 ...

最新文章

  1. 学习java技术有前途吗
  2. 【每日一算法】填充同一层的兄弟节点
  3. 工作10年从大公司离职去小公司当CTO,被同事鄙视竟然不回netty
  4. 论文笔记 DNorm: disease name normalization with pairwise learning to rank
  5. python批量读取文件夹中的所有excel文件-python遍历文件夹下所有excel文件
  6. 算法练习——ACM_1001_Exponentiation
  7. ABAP 如何实现屏幕字段不可输入
  8. 数学之美系列12(转帖)
  9. CF1497E2 Square-free division (hard version)
  10. php算次方,php怎么计算几次方
  11. 牛客网-这是一个沙雕题
  12. 俄罗斯方块游戏设计的有关问题
  13. 终端SSH工具SecureCRT 9.2.0 for Mac
  14. Dota2 AI开发(一)环境配置
  15. Qt之Cannot retrieve debugging output.
  16. 分布式文件系统(DFS)浅析
  17. ppt密码忘了怎么解除,ppt权限密码怎么解开?
  18. 李小杰_测试工程师简历
  19. LaTeX 公式左对齐与右对齐
  20. EF实体类种的Virtual关键字作用

热门文章

  1. 程序人生:开发,运维,测试,实施哪个好?
  2. cv2画圈写字保存图像
  3. RPG游戏滚动地图原理
  4. 05-初始Mach-O
  5. FebHost域名知识:什么是.br巴西域名,如何注册?
  6. Python正规表示式:不一定要会,但会了超省力
  7. 朋友圈或者qq动态相关的数据库设计
  8. 后台网站的一些功能介绍
  9. 时间模块,os模块,sys模块
  10. 码云 git android,Android studio使用Git上传码云入门教程