pg distinct 改写递归优化(德哥的思路)
德哥的优化思路巨牛逼,这种递归思维真的太吊了,我目前就缺递归思路。
下面SQL1000W行数据,列的选择性很低,只有两个值('1'和'11')都是字符串类型,'1'只有一条数据,'11'有9999999行数据。
慢SQL:
select distinct col from tt;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=169247.11..169247.12 rows=1 width=3) (actual time=5082.733..5082.735 rows=2 loops=1)
Group Key: col
-> Seq Scan on tt (cost=0.00..144247.29 rows=9999929 width=3) (actual time=0.005..275.906 rows=10000000 loops=1)
Planning Time: 0.365 ms
Execution Time: 5082.772 ms
(5 行记录)
CTE递归优化:
WITH RECURSIVE t AS (
(SELECT col FROM tt ORDER BY col LIMIT 1)
UNION ALL
SELECT (SELECT col FROM tt WHERE col > t.col ORDER BY col LIMIT 1)
FROM t
WHERE t.col IS NOT NULL
)
SELECT col FROM t WHERE col IS NOT NULL; QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------
CTE Scan on t (cost=50.84..52.86 rows=100 width=38) (actual time=0.024..0.079 rows=2 loops=1)
Filter: (col IS NOT NULL)
Rows Removed by Filter: 1
CTE t
-> Recursive Union (cost=0.43..50.84 rows=101 width=38) (actual time=0.022..0.076 rows=3 loops=1)
-> Limit (cost=0.43..0.46 rows=1 width=3) (actual time=0.021..0.021 rows=1 loops=1)
-> Index Only Scan using idx_1_2_tt on tt tt_1 (cost=0.43..260443.37 rows=9999929 width=3) (actual time=0.020..0.020 rows=1 loops=1)
Heap Fetches: 0
-> WorkTable Scan on t t_1 (cost=0.00..4.84 rows=10 width=38) (actual time=0.017..0.017 rows=1 loops=3)
Filter: (col IS NOT NULL)
Rows Removed by Filter: 0
SubPlan 1
-> Limit (cost=0.43..0.46 rows=1 width=3) (actual time=0.024..0.024 rows=0 loops=2)
-> Index Only Scan using idx_1_2_tt on tt (cost=0.43..95149.36 rows=3333310 width=3) (actual time=0.024..0.024 rows=0 loops=2)
Index Cond: (col > (t_1.col)::text)
Heap Fetches: 0
Planning Time: 0.096 ms
Execution Time: 0.096 ms
(18 行记录)
里面的逻辑是:
(SELECT col FROM tt ORDER BY col LIMIT 1)
根节点通过order by 升序 找到最小的一条数据作为起点。
递归查询:
SELECT (SELECT col FROM tt WHERE col > t.col ORDER BY col LIMIT 1)
FROM t
WHERE t.col IS NOT NULL
在第一次迭代中,CTE t 包含值'1'。这个查询将在tt表中寻找col大于'1'的最小值。在数据集中,这将是'11'。
在第二次迭代,CTE t 将包含'11'。此时,查询将尝试找到大于'11'的最小值,但没有这样的值,所以返回NULL。
递归结束:
当递归查询返回NULL时,递归结束。这时,CTE t 将包含'1'和'11',返回和distinct 一样逻辑的数据。
理解了整个逻辑后我都吓尿了,就一道算法题,确实要跟巨佬学习才行,加深递归思维。
pg distinct 改写递归优化(德哥的思路)的更多相关文章
- 德哥的PostgreSQL私房菜 - 史上最屌PG资料合集
德哥的PostgreSQL私房菜 - 史上最屌PG资料合集
- 云栖专辑|阿里开发者们的第二个感悟:PG大V德哥的使命感与开放心态
摘要: 2018年12月20日,云栖社区3岁.阿里巴巴常说“晴天修屋顶”,所以我们特别制作了这个专辑——分享给开发者们20个阿里故事,50本书籍. 2015年12月20日,云栖社区上线.2018年12 ...
- 德哥PostgreSQL学习资料汇总(转)
文章来自:https://yq.aliyun.com/articles/59251?spm=5176.100239.bloglist.95.5S5P9S 德哥博客新地址:https://billtia ...
- js递归优化
递归优化 递归在我们平时撸码中会经常用到,不过可能很多人不知道递归的弊端,就是会导致调用栈越来越深.如果没有节制的使用递归可能会导致调用栈溢出. 那什么是递归呢? 递归调用是一种特殊的嵌套调用,是某个 ...
- 使用 CUDA 进行计算优化的两种思路
前言 本文讨论如何使用 CUDA 对代码进行并行优化,并给出不同并行思路对均值滤波的实现. 并行优化的两种思路 思路1: global 函数 在 global 函数中创建出多个块多个线程对矩阵每个元素 ...
- 第七篇:使用 CUDA 进行计算优化的两种思路
前言 本文讨论如何使用 CUDA 对代码进行并行优化,并给出不同并行思路对均值滤波的实现. 并行优化的两种思路 思路1: global 函数 在 global 函数中创建出多个块多个线程对矩阵每个元素 ...
- [06] 优化C#服务器的思路和工具的使用
优化C#服务器的思路和工具的使用 优化服务器之前, 需要先对问题的规模做合理的预估, 然后对关键的数据做采样, 做对比, 看和自己的预估是否一致, 误差大在什么地方, 是预估的不对, 还是系统实现有问 ...
- [转]德哥的PostgreSQL私房菜 - 史上最屌PG资料合集
链接地址:https://yq.aliyun.com/articles/59251
- 【PostgreSQL】资料索引(来源:德哥)
PostgreSQL 多应用场景实践 - 沙箱实验 https://github.com/digoal/blog/blob/master/201805/20180524_02.md 一.GIS < ...
- javascript memoization递归优化
memoize优化递归 function createRec(callback, cache) { cache = cache || []; var rec = function(n) { (n in ...
随机推荐
- 私密离线聊天新体验!llama-gpt聊天机器人:极速、安全、搭载Llama 2
"私密离线聊天新体验!llama-gpt聊天机器人:极速.安全.搭载Llama 2,尽享Code Llama支持!" 一个自托管的.离线的.类似chatgpt的聊天机器人.由美洲驼 ...
- C++ STL 标准模板库(容器总结)算法
C++ 标准模板库STL,是一个使用模板技术实现的通用程序库,该库由容器container,算法algorithm,迭代器iterator,容器和算法之间通过迭代器进行无缝连接,其中所包含的数据结构都 ...
- C/C++ 监控磁盘与目录操作
遍历磁盘容量: #include <stdio.h> #include <Windows.h> void GetDrivesType(const char* lpRootPat ...
- RabbitMQ高级知识(消息可靠性,死信交换机,惰性队列,MQ集群)
服务异步通信-高级篇 消息队列在使用过程中,面临着很多实际问题需要思考: 1.消息可靠性 消息从发送,到消费者接收,会经历多个过程: 其中的每一步都可能导致消息丢失,常见的丢失原因包括: 发送时丢失: ...
- 微信小程序 Path2D 不支持 svg 路径的解决办法
问题 开发一个微信小程序项目的时候需要用到Path2D这个对象,但是发现小程序的Path2D对象不支持实例化的时候直接传入'svg path',导致下面的代码运行的时候报错(浏览器中可运行) #其它代 ...
- Linux的yum源配置总结
本文总结归纳了一系列Linux系统的各种yum配置,虽然不一定是标准配置,但都是自己曾真实测过可用的. 1.RHEL6 本地 yum源配置 2.CentOS6 本地 yum源配置 3.OEL5 本地 ...
- Asp .Net Core 系列:Asp .Net Core 集成 NLog
简介 NLog是一个基于.NET平台编写的日志记录类库,它可以在应用程序中添加跟踪调试代码,以便在开发.测试和生产环境中对程序进行监控和故障排除.NLog具有简单.灵活和易于配置的特点,支持在任何一种 ...
- 【OpenGL ES】第一个案例
1 前言 OpenGL(Open Graphics Library)是由 SGI 公司开发的一套 3D 图形软件接口标准,由于具有体系结构简单合理.使用方便.与操作平台无关等优点,OpenGL 迅 ...
- IDEA从o开始的一系列操作及修改配置-快捷键汇总
IDEA从o开始的一系列操作及修改配置-快捷键汇总 下载IDEA 启动idea 安装svn插件 功能快捷键 先设置提示快捷键(纯属个人喜好) 入门快捷键 查找 编辑 小功能 自动代码提示 自动导包 T ...
- Java设计模式-中介者模式Mediator
介绍 中介者模式(Mediator Pattern),用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式属于行 ...