mysql中的semi-join
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产生的结果集去重。

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

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

对应的匹配条件为:

4. Materializelookup:
将inner-table去重固化成临时表,遍历outer-table,然后在固化表上去寻找匹配。
对应的匹配条件:
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 EXTENDEDplusSHOW WARNINGSshows 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 andWHEREclause were merged into the outer query join list andWHEREclause.Temporary table use for Duplicate Weedout is indicated by
Start temporaryandEnd temporaryin theExtracolumn. Tables that were not pulled out and are in the range ofEXPLAINoutput rows covered byStart temporaryandEnd temporarywill have theirrowidin the temporary table.FirstMatch(in thetbl_name)Extracolumn indicates join shortcutting.LooseScan(in them..n)Extracolumn indicates use of the LooseScan strategy.mandnare key part numbers.
As of MySQL 5.6.7, temporary table use for materialization is indicated by rows with a
select_typevalue ofMATERIALIZEDand rows with atablevalue of<subquery.N>Before MySQL 5.6.7, temporary table use for materialization is indicated in the
Extracolumn byMaterializeif a single table is used, or byStart materializeandEnd materializeif multiple tables are used. IfScanis 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
mysql中的semi-join的更多相关文章
- Mysql 中Left/Right join on后面and和where条件查询的差异-Mysql SQL运算符是有优先级
一.Mysql中Left/Right join on后面and和where条件查询的差异 1.建两张测试表,一张商户定义表.一张商户操作状态明细表 1)商户定义表 CREATE TABLE hope. ...
- MySQL中使用INNER JOIN来实现Intersect并集操作
MySQL中使用INNER JOIN来实现Intersect并集操作 一.业务背景 我们有张表设计例如以下: CREATE TABLE `user_defined_value` ( `RESOURCE ...
- hive中left semi join 与join 的区别
LEFT SEMI JOIN:左半开连接会返回左边表的记录,前提是其记录对于右边表满足ON语句中的判定条件.对于常见的内连接(INNER JOIN),这是一个特殊的,优化了的情况.大多数的SQL方言会 ...
- 关于MySQL中的left join、on、where的一点深入
原文地址:http://www.oschina.net/question/89964_65912?sort=default&p=3#answers 即使你认为自己已对 MySQL 的 LEFT ...
- MySQL 通过semi join 优化子查询
半连接是MySQL 5.6.5引入的,多在子查询exists中使用,对外部row source的每个键值,查找到内部row source匹配的第一个键值后就返回,如果找到就不用再查找内部row sou ...
- MySQL中链接查询inner join与left join使用
连接查询其实就是对两个表记录做笛卡尔乘积.如果不指定连接条件的话,则会对每行都做笛卡尔乘积,这样最后返回的结果树就会是两个表记录数的乘积:如果指定则,则仅对符合列条件的行进行笛卡尔乘积,并返回结果.在 ...
- mysql中的几种join 及 full join问题
[注意]:Oracle数据库支持full join,mysql是不支持full join的,但仍然可以同过左外连接+ union+右外连接实现 初始化SQL语句: /*join 建表语句*/ ...
- MySQL中基本的多表连接查询教程
一.多表连接类型1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用',' 如: SELECT * FROM table1 CROSS JOIN ...
- Mysql中的语句优化
1.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我们要重点关注的数据: type列,连接类型.一个好的SQL语句至少要 ...
- mysql中的JOIN用法总结
join是mysql中一个基础的关键词,一般在多表连接查询中使用,这里做一下总结 1.JOIN的语法格式 table_references: table_reference [, table_refe ...
随机推荐
- Yii2 GridView自定义链接之重写 ActionColumn
最近刚开始用yii2,真是超棒的,但是也有许多不足的地方,今天要说的就是GridView链接问题. <?= GridView::widget([ 'dataProvider' => $ ...
- Ubuntu系统启用Apache Mod_rewrite模块
在终端中执行 sudo a2enmod rewrite 指令后,即启用了 Mod_rewrite 模块. 另外,也可以通过将 /etc/apache2/mods-available/rewrite.l ...
- PHP Forms
<html><body><form action="welcome.php" method="post">Name: < ...
- min-height最小高度的实现(兼容IE6、IE7、FF)(解决IE6不兼容min-height)
<!doctype html><html> <head> <meta charset="UTF-8"> <meta name= ...
- nginx+c+cgi开发
http://blog.csdn.net/marising/article/details/3932938 1.Nginx 1.1.安装 Nginx 的中文维基 http://wiki.codemon ...
- C++学习笔记2:关于开发
一.简单的开发流程 (1)定义要被解决的问题: 明确定义待被解决问题,比如具体实现什么功能等. (2)设计解决问题的方法: 好方法的有哪些特点: 1.方法明确: 2.规范化:(已被验证过) 3.模块化 ...
- Aborting commit: 'XXXXXXXX'remains in conflict错误
今天在提交项目文件到本地SVN时提示错误如下: 过期:”global.php“在事务”21-1“, You have to update your working copy first. 运行upda ...
- com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 数据库报错
-- 查询mysql 数据库链接空闲时间持有最大空闲时间,单位为秒 SHOW VARIABLES WHERE VAriable_name = 'interactive_timeout'; -- 会出现 ...
- Flume NG之Interceptor简介
转载地址:http://www.cnblogs.com/lxf20061900/p/3658172.html 有的时候希望通过Flume将读取的文件再细分存储,比如讲source的数据按照业务类型分开 ...
- test Windows Live Writer
1, 下载Live Writer http://windows.microsoft.com/zh-cn/windows-live/essentials-other#essentials=overvie ...