当前位置:网站首页>【MySQL】表连接为什么比子查询快
【MySQL】表连接为什么比子查询快
2022-06-28 15:33:00 【Ch.yang】
1. 前言
查了网上很多资料,最后回归官网的算法介绍。与其说对比子查询和表连接,更合适的说法是对比Nested-Loop
和 Block Nested-Loop
的时间效率。总的来说,表连接更好得触发 Block Nested-Loop
算法,用空间换时间,所以单从效率的角度出发,选择表连接是个比较不错的选择。下文的伪代码全部来自于官方。
2. Nested-Loop
的算法思路
for each row in t1 matching range {
for each row in t2 matching reference key {
for each row in t3 {
if row satisfies join conditions, send to client
}
}
}
2.1 复杂度预估
设t1,t2,t3数据量都为3行,现进行节点遍历
3. Block Nested-Loop
的算法思路
如果出现了表t1, t2, t3。先缓存t1,t2表的循环产生的组合,然后循环t3。t3所有行匹配缓存,连接成功则收集到结果集。
- 现假设缓存容量足够大
for each row in t1 matching range {
for each row in t2 matching reference key {
store used columns from t1, t2 in join buffe
}
}
for each row in t3 {
for each t1, t2 combination in join buffer {
if row satisfies join conditions, send to client
}
}
3.1 复杂度预估
3.2 Block Nested-Loop
减少时间复杂度的思想
空间换时间
- 缓存了
Nested-Loop
(如下第一个图) 需要重复遍历的外层循环 - 观察外层循环的节点都只会被遍历一次,就进入缓存。随着数量级增大,缓存带来的提效呈线性增长
缓存适度使用,分片处理
- 缓存不能做成无界的,Mysq的处理方式:用全局变量限制缓存大小,最大缓存容量为分片,分片数据满后进行匹配再清掉缓存。
for each row in t1 matching range {
for each row in t2 matching reference key {
store used columns from t1, t2 in join buffer
if buffer is full {
for each row in t3 {
for each t1, t2 combination in join buffer {
if row satisfies join conditions, send to client
}
}
empty join buffer
}
}
}
if buffer is not empty {
for each row in t3 {
for each t1, t2 combination in join buffer {
if row satisfies join conditions, send to client
}
}
}
4. 子查询优化
优化子查询
原文:Development is ongoing, so no optimization tip is reliable for the long term. The following list provides some interesting tricks that you might want to play with.
释义:随着开发的演进,没有一种优化建议是长期可靠的。但是有一些有趣的技巧建议可以给到阅读者。
将子查询重写成连接
原文:A LEFT [OUTER] JOIN can be faster than an equivalent subquery because the server might be able to optimize it better—a fact that is not specific to MySQL Server alone.Today, MySQL Server and many other modern database systems offer a wide range of outer join types.
简洁释义:一个外部连接会比等价的子查询效率更高,事实上除了MySQL服务器,大多数的数据库都有这种表现。
-- 将in改写成表连接
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
SELECT DISTINCT t1.* FROM t1, t2 WHERE t1.id=t2.id;
// ---
-- not in 或者 not exists改写成表连接
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2);
SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
SELECT table1.*
FROM table1 LEFT JOIN table2 ON table1.id=table2.id
WHERE table2.id IS NULL;
5. 参考资料
官网相关资料:
MySQL5.7 子查询
MySQL5.7 优化子查询
MySQL5.7 将子查询重写成连接
MySQL5.7 循环相关算法
边栏推荐
- The k-th element in the array [heap row + actual time complexity of heap building]
- Oracle11g database uses expdp to back up data every week and upload it to the backup server
- MIPS汇编语言学习-03-循环
- 力扣今日题-522. 最长特殊序列
- MIPS汇编语言学习-01-两数求和以及环境配置、如何运行
- Fleet | "backstage exploration" issue 3: status management
- Notes to distributed theory
- 开源大咖说 - Linus 与 Jim 对话中国开源
- A bug liver a week I can't help mentioning issue
- R语言ggplot2可视化:使用patchwork包将两个ggplot2可视化结果横向构成新的结果可视化组合图(使用|符号)
猜你喜欢
[leetcode] 13. Roman numeral to integer
Realization of a springboard machine
征文投稿丨使用轻量应用服务器搭建博客环境
使用Karmada实现Helm应用的跨集群部署
Leetcode 705. Design hash collection
GCC efficient graph revolution for joint node representationlearning and clustering
Expand Disk C (allocate the memory of disk d to Disk C)
See how the interface control devaxpress WinForms creates a virtual keyboard
C语言基础语法
MIPS汇编语言学习-02-逻辑判断-前台输入
随机推荐
一种跳板机的实现思路
A bug liver a week I can't help mentioning issue
Spark SQL generate JSON
扩充C盘(将D盘的内存分给C盘)
Cross cluster deployment of helm applications using karmada
C#/VB. Net to convert PDF to excel
实验6 8255并行接口实验【微机原理】【实验】
openGauss内核:SQL解析过程分析
Xinchuang operating system -- kylin kylin desktop operating system (project 10 security center)
Privacy computing fat - offline prediction
C语言基础语法
【LeetCode】13、罗马数字转整数
Curve 替换 Ceph 在网易云音乐的实践
Opengauss kernel: analysis of SQL parsing process
使用Karmada实现Helm应用的跨集群部署
分布式 CAP 定理的前世今生
MIPS assembly language learning-01-sum of two numbers, environment configuration and how to run
R语言ggplot2可视化:使用patchwork包(直接使用加号+)将两个ggplot2可视化结果横向组合起来形成单个可视化结果图
C语言学习-19-全排列
VS2013 帮助文档中没有 win32/com