写点什么

9 个 SQL 运维常遇到的问题

  • 2022-10-12
    中国香港
  • 本文字数:2243 字

    阅读完需:约 7 分钟

9个SQL运维常遇到的问题

本文分享自华为云社区《GaussDB(DWS) SQL性能问题案例集》,作者:黎明的风。


本文重点介绍单个 SQL 语句持续执行慢的场景。我们可以对执行慢的 SQL 进行单独分析,SELECT、INSERT、UPDATE 等语句都可以使用 explain verbose + SQL 语句输出查询计划来进行分析,这样只输出查询计划,语句不会被实际的执行。


如果查询计划只出现__REMOTE_FQS_QUERY__或__REMOTE_LIGHT_QUERY__,看不到具体的计划,可以先执行 set enable_fast_query_shipping to off; 然后再重新打印执行计划。


经常遇到的问题有以下几个:

【案例 1】语句中包含不下推的函数


检查查询计划中是否包含_REMOTE_TABLE_QUERY_关键字, 如果有则表示语句没有下推,数据需要从 DN 上收取到 CN 上,然后语句在 CN 上执行。语句不下推原因,要从 CN 的日志中查找,搜索的关键字为:SQL can’t be shipped,以下为函数造成的不下推例子:


LOG: SQL can't be shipped, reason: Function Fun1() can not be shipped


此外如果出现以下几种不下推的关键字:__REMOTE_GROUP_QUERY__、__REMOTE_LIMIT_QUERY__、

__REMOTE_SORT_QUERY__。这种需要检查 enable_stream_operator 参数是否处于关闭状态,一般来说打开 STREAM 开关后,语句就可以下推执行了。


如果出现以下两种关键字,表示语句可以下推执行:


__REMOTE_FQS_QUERY__:表明语句走了 Fast Query Shipping(FQS),SQL 语句会下发到 DN 上执行,并且各 DN 之间没有数据交互,常见的场景有过滤条件为等值查询(where id = 1),或者关联的列是表的分布列的查询(where t1.id = t2.id)。


__REMOTE_LIGHT_QUERY__:表明语句走了 Light Proxy(CN 轻量化),将语句下发给了单个 DN 去处理,常见的场景过滤条件是分布列的等值查询(where id = 1),或者向一个 DN 插入数据的 INSERT 语句。

【案例 2】表上有索引但没有走索引扫描,进行了全表扫描


从查询计划中可以看到 Seq Scan 或 CStore Scan 这样的关键字,如下所示:


对于行存表:-> Seq Scan on t1


对于列存表:-> CStore Scan on col_t1


出现这种问题通常有以下几种情况:


没有对所查询的表收集统计信息


如果表的实际行数很大,而估算行数很小,查询时可能会走全表顺序扫描,造成执行速度慢。此时通过 analyze 表更新统计信息,让优化器选择最佳的查询计划,一般就可以解决执行慢的问题。

【案例 3】模糊匹配没有走索引


后模糊匹配查询可以通过建立一个 BTREE 索引来实现,需要根据数据类型设置索引的 operator,对于 text,varchar 和 char 分别设置和 text_pattern_ops,varchar_pattern_ops 和 bpchar_pattern_ops。


例如 c1 列的类型为 text,创建索引时增加 text_pattern_ops。


CREATE INDEX ON t1 (c1 text_pattern_ops);


创建索引后,可以看到语句执行时会使用到前面创建的索引,执行速度会变快。


【案例 4】创建索引时所指定列的顺序问题


多列复合索引的组织结构与单列字段索引结构类似,按索引内表达式指定的顺序编排。当创建多列复合索引时,选择什么样的列的顺序,对查询性能会带来一定的影响。


例如按照 c_date,c1 和 c2 列的顺序建立检索,如果符合 c_date 条件的数据很多,通过这个索引扫描的数据就很会很多,造成执行时间长。



新建多列复合索引,将查询条件里的等值条件的列放到索引列的前面,先使用等值进行过滤,需要扫描的数据变少,查询变快。


【案例 5】分区表没有分区剪枝进行了全表扫描


问题背景:XSYX 局点使用 MERGE INTO 语句将每天的数据入库到表里,目标表为分区表,业务上线运行一段时间后发现 MERGE INTO 速度逐渐变慢。


原因分析:MERGE INTO 语句的源表和目标表都是分区表,当前仅对源表增加了时间的过滤条件,可以进行分区剪枝。目标表由于没有指定时间过滤条件,进行的是全表扫描,随着每日的入库业务运行,目标表的数据量越来越大,造成执行速度越来越慢。


解决方案:由于源表的数据在 MERGE INTO 时会导入到目标表的对应分区里,可以对目标表增加时间的过滤条件进行分区剪枝。


业务修改前的查询计划:



对目标表增加了时间过滤条件后的计划显示可以走分区剪枝:


【案例 6】表数据在 DN 节点上有存储倾斜


从查询计划中的 A-time 可以看到最长和最短的执行时间相差很大,说明在不同 DN 上扫描数据的时间不同。



在查询计划的 DN 信息中,通过 rows 可以看出在 datanode1 上扫描的数据量明显多于 datanode2,说明有存储倾斜,这种情况建议对表进行合理的设计,选择合适的分布列,将数据均匀分布到所有的 DN 上。


【案例 7】自定义函数引起执行慢


问题现象:查询语句比较简单,两个表做关联后输出了其中一列的值,在输出前增加了一个自定义函数对数据进行了处理。


原因分析:自定义函数里逻辑相对复杂,包含了对表的查询及数据计算逻辑,造成执行变慢。



解决方案;业务上对自定义函数进行性能优化。

【案例 8】查询视图执行时间长


问题现象:某 YD 局点从 C80 版本迁移数据到 8.1.1 版本后,查询 PG_STAT_USER_TABLES 视图的时间由几分钟变成半个小时都不出结果。


原因分析:8.1.1 版本中的 PG_STAT_USER_TABLES 视图在获取插入、更新、删除的行数的字段数值时,每一条记录都涉及到 CN 和 DN 的交互,在数据量和集群规模大的情况下耗时较多。


解决方案:建议根据应用的实际需要,将视图定义中不需要的函数注释掉以提升查询效率。

【案例 9】关闭 indexscan 和 bitmapscan 后可以使用并行提升性能


问题现象: 查询计划中显示走了 Index Scan,通过索引查询出的数据量比较大,速度慢。


原因分析:由于使用索引扫描时无法使用并行查询,当索引访问的数据量大时执行速度较慢。


解决方案:将 enable_indexscan 和 enable_bitmapscan 参数关闭,设置 query_dop 后走并行查询。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 4
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
9个SQL运维常遇到的问题_数据库_华为云开发者联盟_InfoQ写作社区