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 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(
in thetbl_name
)Extra
column indicates join shortcutting.LooseScan(
in them
..n
)Extra
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
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 ...
随机推荐
- redis补充和rabbitmq讲解
线程池: redis发布订阅: rabbitMQ: MySQL; python pymysql: python orm SQLAchemy: paramiko: 堡垒机: 1.线程池 1.1 cont ...
- php大力力 [026节] php开发状态要随时做好整理工作
php大力力 [026节] php开发状态要随时做好整理工作: 1.整理了开发目录,以及文件命名: 2.做了各个页面的快捷方式: 3.把浏览器safari的很多没来得及消化的页面链接,写入了我的在线 ...
- Interview----将一棵二叉树转换成其镜像
题目:输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点. 用递归和循环两种方法完成树的镜像转换. 例如输入: 8 / ...
- PHP图像处理之画图
PHP图像处理 画图 验证码,统计图 安装GD库-----LAMP 安装后在D:\APMServ5.2.6\PHP\ext文件中有php_gd2.dll文件 ...
- PHP实现简单计算器
<!--简单的计算器--> <!DOCTYPE html> <html> <head> <title>PHP实现简单计算器</titl ...
- [转]MMORPG服务器架构
MMORPG服务器架构 一.摘要 1.网络游戏MMORPG整体服务器框架,包括早期,中期,当前的一些主流架构2.网络游戏网络层,包括网络协议,IO模型,网络框架,消息编码等.3.网络游戏的场景管理,A ...
- 第一个Sprint冲刺事后诸葛报告
用户反馈:软件一般般,比较传统. 用户数量:5 团队改进建议:选择题与填空题太没有新意了,需要新的创新功能. 1.每个成员第一个sprint阶段有何需要改进? 成员 需要改进 邵家文 需要更多的技术的 ...
- typeof、offsetof、container_of的解释
链表是内核最经典的数据结构之一,说到链表就不得不提及内核最经典(没有之一)的宏container_of. container_of似乎就是为链表而生的,它的主要作用是根据一个结构体变量中的一个域成员变 ...
- unable to open sync connection
有些时候,在你向连接好的Android机器中按照程序时会遭遇失败,logcat提示“unable to open sync connection”. 一般情况下,重启手机几乎肯定可以解决这个问题. 如 ...
- Linux磁盘文件的命名
磁盘的常用接口有两种:IDE和SATA接口,目前主流的是SATA接口. IDE接口由IDE扁平电缆线连接,一个电缆可连接两个IDE接口,通常主机又都会提供两个IDE接口,因此最多可以接到四个IDE设备 ...