腾讯云TDSQL PostgreSQL版 -最佳实践 |优化 SQL 语句
查看是否为分布键查询
postgres=# explain select * from tbase_1 where f1=1;
QUERY PLAN
--------------------------------------------------------------------------------
Remote Fast Query Execution (cost=0.00..0.00 rows=0 width=0)
Node/s: dn001, dn002
-> Gather (cost=1000.00..7827.20 rows=1 width=14)
Workers Planned: 2
-> Parallel Seq Scan on tbase_1 (cost=0.00..6827.10 rows=1 width=14)
Filter: (f1 = 1)
(6 rows)
postgres=# explain select * from tbase_1 where f2=1;
QUERY PLAN
--------------------------------------------------------------------------------
Remote Fast Query Execution (cost=0.00..0.00 rows=0 width=0)
Node/s: dn001
-> Gather (cost=1000.00..7827.20 rows=1 width=14)
Workers Planned: 2
-> Parallel Seq Scan on tbase_1 (cost=0.00..6827.10 rows=1 width=14)
Filter: (f2 = 1)
(6 rows)
如上,第一个查询为非分布键查询,需要发往所有节点,这样最慢的节点决定了整个业务的速度,需要保持所有节点的响应性能一致,如第二个查询所示,业务设计查询时尽可能带上分布键。
查看是否使用索引
postgres=# create index tbase_2_f2_idx on tbase_2(f2);
CREATE INDEX
postgres=# explain select * from tbase_2 where f2=1;
QUERY PLAN
-------------------------------------------------------------------------------------
Remote Fast Query Execution (cost=0.00..0.00 rows=0 width=0)
Node/s: dn001, dn002
-> Index Scan using tbase_2_f2_idx on tbase_2 (cost=0.42..4.44 rows=1 width=14)
Index Cond: (f2 = 1)
(4 rows)
postgres=# explain select * from tbase_2 where f3='1';
QUERY PLAN
--------------------------------------------------------------------------------
Remote Fast Query Execution (cost=0.00..0.00 rows=0 width=0)
Node/s: dn001, dn002
-> Gather (cost=1000.00..7827.20 rows=1 width=14)
Workers Planned: 2
-> Parallel Seq Scan on tbase_2 (cost=0.00..6827.10 rows=1 width=14)
Filter: (f3 = '1'::text)
(6 rows)
postgres=#
第一个查询使用了索引,第二个没有使用索引,通常情况下,使用索引可以加速查询速度,但索引也会增加更新的开销。
查看是否为分布 key join
postgres=# explain select tbase_1.* from tbase_1,tbase_2 where tbase_1.f1=tbase_2.f1 ;
QUERY PLAN
------------------------------------------------------------------------------------------------
Remote Subquery Scan on all (dn001,dn002) (cost=29.80..186.32 rows=3872 width=40)
-> Hash Join (cost=29.80..186.32 rows=3872 width=40)
Hash Cond: (tbase_1.f1 = tbase_2.f1)
-> Remote Subquery Scan on all (dn001,dn002) (cost=100.00..158.40 rows=880 width=40)
Distribute results by S: f1
-> Seq Scan on tbase_1 (cost=0.00..18.80 rows=880 width=40)
-> Hash (cost=18.80..18.80 rows=880 width=4)
-> Seq Scan on tbase_2 (cost=0.00..18.80 rows=880 width=4)
(8 rows)
postgres=# explain select tbase_1.* from tbase_1,tbase_2 where tbase_1.f2=tbase_2.f1 ;
QUERY PLAN
---------------------------------------------------------------------------------
Remote Fast Query Execution (cost=0.00..0.00 rows=0 width=0)
Node/s: dn001, dn002
-> Hash Join (cost=18904.69..46257.08 rows=500564 width=14)
Hash Cond: (tbase_1.f2 = tbase_2.f1)
-> Seq Scan on tbase_1 (cost=0.00..9225.64 rows=500564 width=14)
-> Hash (cost=9225.64..9225.64 rows=500564 width=4)
-> Seq Scan on tbase_2 (cost=0.00..9225.64 rows=500564 width=4)
(7 rows)
第一个查询需要数据重分布,而第二个不需要,分布键 join 查询性能会更高。
查看 join 发生的节点
postgres=# explain select tbase_1.* from tbase_1,tbase_2 where tbase_1.f1=tbase_2.f1 ;
QUERY PLAN
-----------------------------------------------------------------------------------------------
Hash Join (cost=29.80..186.32 rows=3872 width=40)
Hash Cond: (tbase_1.f1 = tbase_2.f1)
-> Remote Subquery Scan on all (dn001,dn002) (cost=100.00..158.40 rows=880 width=40)
-> Seq Scan on tbase_1 (cost=0.00..18.80 rows=880 width=40)
-> Hash (cost=126.72..126.72 rows=880 width=4)
-> Remote Subquery Scan on all (dn001,dn002) (cost=100.00..126.72 rows=880 width=4)
-> Seq Scan on tbase_2 (cost=0.00..18.80 rows=880 width=4)
(7 rows)
postgres=# set prefer_olap to on;
SET
postgres=# explain select tbase_1.* from tbase_1,tbase_2 where tbase_1.f1=tbase_2.f1 ;
QUERY PLAN
------------------------------------------------------------------------------------------------
Remote Subquery Scan on all (dn001,dn002) (cost=29.80..186.32 rows=3872 width=40)
-> Hash Join (cost=29.80..186.32 rows=3872 width=40)
Hash Cond: (tbase_1.f1 = tbase_2.f1)
-> Remote Subquery Scan on all (dn001,dn002) (cost=100.00..158.40 rows=880 width=40)
Distribute results by S: f1
-> Seq Scan on tbase_1 (cost=0.00..18.80 rows=880 width=40)
-> Hash (cost=18.80..18.80 rows=880 width=4)
-> Seq Scan on tbase_2 (cost=0.00..18.80 rows=880 width=4)
(8 rows)
第一个 join 在 cn 节点执行,第二个在 dn 上重分布后再 join,业务设计上,一般 OLTP 类业务在 cn 上进行少数据量 join ,性能会更好。
查看并行的 worker 数
postgres=# explain select count(1) from tbase_1;
QUERY PLAN
---------------------------------------------------------------------------------------
Finalize Aggregate (cost=118.81..118.83 rows=1 width=8)
-> Remote Subquery Scan on all (dn001,dn002) (cost=118.80..118.81 rows=1 width=0)
-> Partial Aggregate (cost=18.80..18.81 rows=1 width=8)
-> Seq Scan on tbase_1 (cost=0.00..18.80 rows=880 width=0)
(4 rows)
postgres=# analyze tbase_1;
ANALYZE
postgres=# explain select count(1) from tbase_1;
QUERY PLAN
----------------------------------------------------------------------------------------------------
Parallel Finalize Aggregate (cost=14728.45..14728.46 rows=1 width=8)
-> Parallel Remote Subquery Scan on all (dn001,dn002) (cost=14728.33..14728.45 rows=1 width=0)
-> Gather (cost=14628.33..14628.44 rows=1 width=8)
Workers Planned: 2
-> Partial Aggregate (cost=13628.33..13628.34 rows=1 width=8)
-> Parallel Seq Scan on tbase_1 (cost=0.00..12586.67 rows=416667 width=0)
(6 rows)
上面第一个查询没走并行,第二个查询 analyze 后走并行才是正确的,建议大数据量更新再执行 analyze。
查看各节点的执行计划是否一致
./tbase_run_sql_dn_master.sh "explain select * from tbase_2 where f2=1"
dn006 --- psql -h 172.16.0.13 -p 11227 -d postgres -U tbase -c "explain select * from tbase_2 where f2=1"
QUERY PLAN
-----------------------------------------------------------------------------
Bitmap Heap Scan on tbase_2 (cost=2.18..7.70 rows=4 width=40)
Recheck Cond: (f2 = 1)
-> Bitmap Index Scan on tbase_2_f2_idx (cost=0.00..2.18 rows=4 width=0)
Index Cond: (f2 = 1)
(4 rows)
dn002 --- psql -h 172.16.0.42 -p 11012 -d postgres -U tbase -c "explain select * from tbase_2 where f2=1"
QUERY PLAN
-------------------------------------------------------------------------------
Index Scan using tbase_2_f2_idx on tbase_2 (cost=0.42..4.44 rows=1 width=14)
Index Cond: (f2 = 1)
(2 rows)
两个 dn 的执行计划不一致,最大可能是数据倾斜或者是执行计划被禁用。
如有可能,DBA 可以配置在系统空闲时执行全库 analyze 和 vacuum。
腾讯云TDSQL PostgreSQL版 -最佳实践 |优化 SQL 语句的更多相关文章
- 腾讯云TDSQL MySQL版 - 开发指南 二级分区
TDSQL MySQL版 目前支持 Range 和 List 两种格式的二级分区,具体建表语法和 MySQL 分区语法类似. 二级分区语法 一级 Hash,二级 List 分区示例如下: MySQL ...
- 腾讯云TDSQL MySQL版 - 开发指南 分布式事务
由于事务操作的数据通常跨多个物理节点,在分布式数据库中,类似方案即称为分布式事务. TDSQL MySQL版 支持普通分布式事务协议和 XA 分布式事务协议.TDSQL MySQL版(内核5.7或以上 ...
- 286万QPS!腾讯云TDSQL打造数据库领域的“超音速战机”
Bloodhound SSC超音速汽车将陆地极限速度提升到1678公里/小时,号称陆地“超音速战斗机”.无独有偶,同样也在2017年,在英特尔®.腾讯金融云团队的共同见证下,腾讯云数据库TDSQL采用 ...
- 腾讯云TDSQL审计原理揭秘
版权声明:本文由孙勇福原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/244 来源:腾云阁 https://www.qclo ...
- MaxCompute 构建企业云数据仓库CDW的最佳实践建议
在本文中阿里云资深产品专家云郎分享了基于阿里云 MaxCompute 构建企业云数据仓库CDW的最佳实践建议. 本文内容根据演讲视频以及PPT整理而成. 大家下午好,我是云郎,之前在甲骨文做企业架构师 ...
- 强强联袂!腾讯云TDSQL与国双战略签约,锚定国产数据库巨大市场
日前,腾讯云计算(北京)有限责任公司与北京国双科技有限公司签署了<国产数据库产品战略合作协议>,双方将在数据库技术方面展开深度合作,通过分布式交易型数据库的联合研发.产品服务体系建设.品牌 ...
- 腾讯云TDSQL监控库密码忘记问题解决实战
首先,给大家介绍一下TDSQL.TDSQL MySQL 版(TDSQL for MySQL)是腾讯打造的一款分布式数据库产品,具备强一致高可用.全球部署架构.分布式水平扩展.高性能.企业级安全等特性, ...
- 腾讯云CDB的AI技术实践:CDBTune
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:邢家树,高级工程师,目前就职于腾讯TEG基础架构部数据库团队.腾讯数据库技术团队维护MySQL内核分支TXSQL,100%兼容原生My ...
- 揭秘华为云GaussDB(for Influx)最佳实践:hint查询
摘要:GaussDB(for Influx)通过提供hint功能,在单时间线的查询场景下,性能有大幅度的提升,能有效满足客户某些特定场景的查询需求. 本文分享自华为云社区<华为云GaussDB( ...
随机推荐
- 温故知新,Blazor遇见大写人民币翻译机(ChineseYuanParser),践行WebAssembly SPA的实践之路
背景 在之前<温故知新,.Net Core遇见Blazor(FluentUI),属于未来的SPA框架>中我们已经初步了解了Blazor的相关概念,并且根据官方的指引完成了<创建我的第 ...
- 详解C++中的多态和虚函数
一.将子类赋值给父类 在C++中经常会出现数据类型的转换,比如 int-float等,这种转换的前提是编译器知道如何对数据进行取舍.类其实也是一种数据类型,也可以发生数据转换,但是这种转换只有在 子类 ...
- 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法
"为什么这个功能用不了?" 程序员:"清一下缓存" 上篇洞悉系列文章给大家详细介绍了MySQL的存储内幕:洞悉MySQL底层架构:游走在缓冲与磁盘之间.既然聊过 ...
- hdu 6025 前缀 后缀 gcd
大致题意: 去掉一个元素能使这个数列的GCD最大为多少 分析: 我们求一个数列的GCD,是先求前两个元素的GCD,然后将这个GCD值在与下一个元素进行GCD运算.由此可知进行GCD运算的顺序对最终的结 ...
- ArrayList 从源码角度剖析底层原理
本篇文章已放到 Github github.com/sh-blog 仓库中,里面对我写的所有文章都做了分类,更加方便阅读.同时也会发布一些职位信息,持续更新中,欢迎 Star 对于 ArrayList ...
- 家庭账本开发day02
今日完成 今天主要进行了前台界面的构架,利用layUI已有的模板编写新增账单界面 然后进行了后端的Bean和Servlet的初步编写,实现数据库的构建. 遇到问题 获取前端传输数据,并添加数据到数据库 ...
- [刘阳Java]_MySQL数据优化总结_查询备忘录
数据库优化是在后端开发中必备技能,今天写一篇MySQL数据优化的总结,供大家看看 一.MySQL数据库优化分类 我们通过一个图片形式来看看数据优化一些策略问题 不难看出,优化有两条路可以选择:硬件与技 ...
- Vim的操作
记录下vim的快捷键操作: I 进入编辑: Esc 退出编辑: 按ESC键 跳到命令模式,然后::w 保存文件但不退出vi:w file 将修改另外保存到file中,不退出vi:w ...
- java并发编程基础——线程池
线程池 由于启动一个线程要与操作系统交互,所以系统启动一个新的线程的成本是比较高的.在这种情况下,使用线程池可以很好的提升性能,特别是程序中涉及创建大量生命周期很短暂的线程时. 与数据库连接池类似,线 ...
- Python+Requests+异步线程池爬取视频到本地
1.本次项目为获取梨视频中的视频,再使用异步线程池下载视频到本地 2.获取视频时,其地址中的Url是会动态变化,不播放时src值为图片的地址,播放时src值为mp4格式 3.查看视频链接是否存在aja ...