semi-join子查询优化 -- Duplicate Weedout策略
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策略的更多相关文章
- semi-join子查询优化 -- semi-join Materialization策略
semi-join Materialization 是用于semi-join的一种特殊的子查询物化技术.通常包含两种策略:1.Materialization/lookup2.Materializati ...
- MySQL 通过semi join 优化子查询
半连接是MySQL 5.6.5引入的,多在子查询exists中使用,对外部row source的每个键值,查找到内部row source匹配的第一个键值后就返回,如果找到就不用再查找内部row sou ...
- semi-join子查询优化 -- FirstMatch策略
FirstMatch执行semi-join子查询的一种策略. 类似于MySQL 5.x中如何执行in.exists子查询. 让我们以搜索拥有大城市的国家为例: select * from Countr ...
- Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化
参考书籍<mysql是怎样运行的> 非常推荐这本书,通俗易懂,但是没有讲mysql主从等内容 书中还讲解了本文没有提到的子查询优化内容, 本文只总结了常见的子查询是如何优化的 系列文章目录 ...
- postgresql子查询优化(提升子查询)
问题背景 在开发项目过程中,客户要求使用gbase8s数据库(基于informix),简单的分页页面响应很慢.排查发现分页sql是先查询出数据在外面套一层后再取多少条,如果去掉嵌套的一层,直接获取则很 ...
- 【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)
原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_ ...
- 标量子查询优化(用group by 代替distinct)
标量子查询优化 当使用另外一个SELECT 语句来产生结果中的一列的值的时候,这个查询必须只能返回一行一列的值.这种类型的子查询被称为标量子查询 在某些情况下可以进行优化以减少标量子查询的重复执行,但 ...
- PostgreSQL查询优化之子查询优化
子查询优化 上拉子连接 上拉子连接主要是把ANY和EXIST子句转换为半连接 void pull_up_sublinks(PlannerInfo *root) { Node *jtnode; //子连 ...
- 转载:left join和left semi join的联系和区别
1.联系 他们都是 hive join 方式的一种,join on 属于 common join(shuffle join/reduce join),而 left semi join 则属于 map ...
随机推荐
- 【python】文件下载---基础版
基于TCP协议的基础版本,不支持大文件 Client.py import socket def main(): # 1. 创建套接字 tcp_socket = socket.socket(socket ...
- Flask介绍及简单使用
Flask Django是一个大而全的框架,Flask是一个轻量级的框架. 区别: Django内部集成了大量的组件:请求处理是逐一封装和传递: Flask本身并没有太多的功能,但是第三方组件非常丰富 ...
- Github 上 10 个值得学习的 Springboot 开源项目
Spring Boot 几乎继承了所有 Spring 框架的优点,同时还可以让项目的配置更简化.编码更简化.部署更方便.近两年受到很多开发者的追捧,也是火热的不行! 下面给大家整理了 10 个 Git ...
- Pods
Pods Pod概念 Pod是kubernetes集群应用中的创建和部署的最小.最简单的kubernetes对象模型单元的基本执行单元.Pod表示在集群中运行的进程. Pod 封装了应用程序的容器(一 ...
- 存储型XSS靶场作业
首先进入靶场:http://59.63.200.79:8082/index.php xss平台使用:xss8c 发现CMS版本号,搜索是否此版本号存在可利用漏洞: 找到存储型xss漏洞,在xss平台生 ...
- php将原数组倒序array_reverse()
1.数组倒序排列 $arr = array(1,2,3); $arr = array_reverse($arr); print_r($arr);
- 用IntelliJ IDEA学习Spring--创建一个简单的项目
这段时间想学习一下Spring,其实之前学过Spring,只是有些忘记了.而且之前学的时候是适用eclipse学习的,现在好像对IntelliJ这个工具使用挺多的,现在就学习一下这个工具的用法,顺便复 ...
- LOJ#2343. 「JOI 2016 Final」集邮比赛 2
题目地址 https://loj.ac/problem/2343 题解 首先处理出\(f[i]\)表示以当前位置开头(J,O,I)的合法方案数.这个显然可以\(O(n)\)处理出来.然后考虑在每个位置 ...
- Spring源码窥探之:单实例Bean的创建过程
finishBeanFactoryInitialization(beanFactory);初始化剩下的所有的单实例(非懒加载)Bean(Instantiate all remaining (non-l ...
- LeetCode(数据库)部门最高工资
), Salary int, DepartmentId int) )) Truncate table Employee ') ') ') ') Truncate table Department ', ...