duplicate weedout是执行semi-join子查询的一种策略。

将semi-join作为一个常规的inner join。然后使用一个临时表,将重复的记录排除。

假设,你有一个查询,你在寻找一个大城市人口占总人口33%以上的国家:

select *
from Country
where
Country.code IN (select City.Country
from City
where
City.Population > 0.33 * Country.Population and
City.Population > 1*1000*1000);

  

如果我们以常规的inner join方式连接表city和country:

inner join会产生重复的记录。这里Germany有三行记录,因为有三个大城市。现在我们将duplicate weedout加入图示中:

这里是用了一个带有主键的临时表,来避免产生多行记录。(Germany有三条记录)

下面是使用duplicate weedout后的执行计划,其中start temporary和end temporary表明使用了临时表:

MariaDB [world]> explain select * from Country where Country.code IN (select City.Country from City where City.Population > 0.33 * Country.Population and City.Population > 1*1000*1000)\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: City
type: range
possible_keys: Population,Country
key: Population
key_len: 4
ref: NULL
rows: 238
Extra: Using index condition; Start temporary
*************************** 2. row ***************************
id: 1
select_type: PRIMARY
table: Country
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 3
ref: world.City.Country
rows: 1
Extra: Using where; End temporary
2 rows in set (0.00 sec)

这个查询会读取city表中的238行记录,而且,它们中的每一个都将在Country表中进行主键查找,这将提供另外238行记录。总共就是476行,需要在临时表中增加238个查找(因为临时表是in-memory的,相对成本较低)。

相同的SQL,如果不适用duplicate weedout,执行计划为:

mysql> explain select * from Country where Country.code IN (select City.Country from City where City.Population > 0.33 * Country.Population and City.Population > 1*1000*1000)
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: Country
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 239
Extra: Using where
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: City
type: index_subquery
possible_keys: Population,Country
key: Country
key_len: 3
ref: func
rows: 18
Extra: Using where
2 rows in set (0.00 sec)

读取的行数是(239+239+18)=4541,就慢多了。

原文地址:

https://mariadb.com/kb/en/library/duplicateweedout-strategy/

semi-join子查询优化 -- Duplicate Weedout策略的更多相关文章

  1. semi-join子查询优化 -- semi-join Materialization策略

    semi-join Materialization 是用于semi-join的一种特殊的子查询物化技术.通常包含两种策略:1.Materialization/lookup2.Materializati ...

  2. MySQL 通过semi join 优化子查询

    半连接是MySQL 5.6.5引入的,多在子查询exists中使用,对外部row source的每个键值,查找到内部row source匹配的第一个键值后就返回,如果找到就不用再查找内部row sou ...

  3. semi-join子查询优化 -- FirstMatch策略

    FirstMatch执行semi-join子查询的一种策略. 类似于MySQL 5.x中如何执行in.exists子查询. 让我们以搜索拥有大城市的国家为例: select * from Countr ...

  4. Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化

    参考书籍<mysql是怎样运行的> 非常推荐这本书,通俗易懂,但是没有讲mysql主从等内容 书中还讲解了本文没有提到的子查询优化内容, 本文只总结了常见的子查询是如何优化的 系列文章目录 ...

  5. postgresql子查询优化(提升子查询)

    问题背景 在开发项目过程中,客户要求使用gbase8s数据库(基于informix),简单的分页页面响应很慢.排查发现分页sql是先查询出数据在外面套一层后再取多少条,如果去掉嵌套的一层,直接获取则很 ...

  6. 【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)

    原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_ ...

  7. 标量子查询优化(用group by 代替distinct)

    标量子查询优化 当使用另外一个SELECT 语句来产生结果中的一列的值的时候,这个查询必须只能返回一行一列的值.这种类型的子查询被称为标量子查询 在某些情况下可以进行优化以减少标量子查询的重复执行,但 ...

  8. PostgreSQL查询优化之子查询优化

    子查询优化 上拉子连接 上拉子连接主要是把ANY和EXIST子句转换为半连接 void pull_up_sublinks(PlannerInfo *root) { Node *jtnode; //子连 ...

  9. 转载:left join和left semi join的联系和区别

    1.联系 他们都是 hive join 方式的一种,join on 属于 common join(shuffle join/reduce join),而 left semi join 则属于 map ...

随机推荐

  1. CentOS安装MySQL8.x

    MySQL的安装 (4,5,6可省略) 声明:CentOS版本为7.6,安装的MySQL版本为8.0.17 1. 首先要卸载掉本机自带的mysql相关,包括MariaDB. rpm -pa | gre ...

  2. 使用Cloudera Manager添加Sentry服务

    使用Cloudera Manager添加Sentry服务 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.通过CM添加Sentry服务 1>.点击添加服务进入CM服务安装向 ...

  3. 用Python添加写入数据到已经存在的Excel的xlsx文件

    # coding:utf-8 from openpyxl import load_workbook import openpyxl # 写入已存在的xlsx文件第一种方法 # class Write_ ...

  4. 项目Beta冲刺(1/7)(追光的人)(2019.5.23)

    所属课程 软件工程1916 作业要求 Beta冲刺博客汇总 团队名称 追光的人 作业目标 描述Beta冲刺每日的scrum和PM报告两部分 队员学号 队员博客 221600219 小墨 https:/ ...

  5. 网络基础知识(http请求)

    http请求的过程 域名解析----TCP连接 ----发送请求-----响应请求----获取html代码----浏览器渲染 TCP是主机对主机层的控制传输协议,提供可靠的连接服务 TCP的三次握手 ...

  6. 安装cuda及之后更新环境变量的方法

    安装参考:https://www.cnblogs.com/fanfzj/p/8521728.html 更新环境变量: 将 CUDA.CUPTI 和 cuDNN 安装目录添加到 %PATH% 环境变量中 ...

  7. [Ignatius and the Princess III] 整数的无序拆分(DP + 生成函数)

    整数的有序拆分就是隔板法,无序拆分则有两种处理方法 DP递推 我们假设P(n,m)P(n,m)P(n,m)是正整数nnn无序拆分为mmm个正整数的方案数 对于某一种拆分,不妨将拆分出来的mmm个数从小 ...

  8. LeetCode 801. Minimum Swaps To Make Sequences Increasing

    原题链接在这里:https://leetcode.com/problems/minimum-swaps-to-make-sequences-increasing/ 题目: We have two in ...

  9. LeetCode 743. Network Delay Time

    原题链接在这里:https://leetcode.com/problems/network-delay-time/ 题目: There are N network nodes, labelled 1  ...

  10. BCB6 如何跨工程(Project)进行源码级调试

    如何跨工程(Project)进行源码级调试 在日常工作中,如何跨工程(Project)进行源码级调试这是个无法回避的问题.例如:一个应用程序工程为“prj_A”,一个动态库工程为“prj_B”,“pr ...