首页 > 其他分享 >GaussDB分区表查询性能异常分析

GaussDB分区表查询性能异常分析

时间:2024-11-27 11:27:37浏览次数:5  
标签:剪枝 GaussDB 查询 索引 分区表 c1 t1 分区

问题现象

使用分区表进行相关查询业务,SQL性能慢。

原因分析

导致分区表业务慢的常见原因有以下几种:

  • 分区索引失效,顺序扫描导致的SQL性能慢
  • 分区表无法进行分区剪枝导致的SQL性能慢
  • SQL计划选择非最优导致的SQL性能慢

处理方法

判断是否存在索引异常的行为

部分分区DDL如果不带UPDATE GLOBAL INDEX子句,会导致分区表Global索引失效。同时用户也可以使用ALTER TABLE或者ALTER INDEX使分区表索引失效。当分区表或者部分分区上索引不可用后,会导致查询SQL无法走索引扫描,从而出现慢SQL场景。

  • 查询索引类型和状态

分区表的索引有两种,Local索引和Global索引。Local索引会在每个分区创建一个索引,Global索引会在整个分区表上创建一个全局索引。对于Local索引,需要确认整个索引自身状态和目标查询分区的索引状态;对于Global索引,只需要确认整个索引自身状态。
可以通过系统表pg_index查询分区表的所有索引,并获取索引是否可用的状态,其索引类型在pg_class中给出。下面给出了查询分区表t1的全部索引状态及索引类型的命令参考:

gaussdb=# select c.relname, i.indisusable, c.relkind from pg_class c join pg_index i on c.oid=i.indexrelid 
    join pg_class r on i.indrelid=r.oid where r.relname='t1'; 
      relname       | indisusable | relkind  
--------------------+-------------+--------- 
 t1_c1_idx          | t           | i 
 t1_c2_tableoid_idx | f           | I

其中indisusable字段为't'表示该索引可用,为'f'表示索引已经失效,在查询业务中该索引无法使用;relkind为'i'表示该索引为Local索引,为'I'表示该索引为Global索引。
或者通过元语句\d命令查询分区表的索引信息:

gaussdb=# \d t1 
      Table "public.t1" 
 Column |  Type   | Modifiers  
--------+---------+----------- 
 c1     | integer |  
 c2     | integer |  
Indexes: 
    "t1_c1_idx" btree (c1) LOCAL TABLESPACE pg_default 
    "t1_c2_tableoid_idx" btree (c2) TABLESPACE pg_default UNUSABLE 
Partition By RANGE(c1) 
Number of partitions: 2 (View pg_partition to check each partition range.)

可以看到表t1的两条索引t1_c1_idx、t1_c2_tableoid_idx被列出。其中t1_c1_idx带有LOCAL关键字,表示该索引为Local索引,t1_c2_tableoid_idx没有LOCAL关键字,表示该索引为Global索引。同时t1_c2_tableoid_idx标记了UNUSABLE,表示该索引不可用。

  • 查询索引分区状态

对于Local索引,还需要确认目标查询分区的索引状态,这个信息可以从系统表pg_partition中查询。

gaussdb=# select p.relname,p.indisusable from pg_partition p join pg_class c on p.parentid=c.oid where c.relname='t1_c1_idx'; 
  relname  | indisusable  
-----------+------------- 
 p1_c1_idx | t 
 p2_c1_idx | f 
(2 rows)

可以看到索引分区p1_c1_idx可用,索引分区p2_c1_idx不可用。在分区p2上的查询无法使用索引t1_c1_idx。

  • 重建异常的索引/索引分区

如果分区表的索引/索引分区状态异常,会导致查询SQL无法走索引扫描,需要重建索引/索引分区。重建索引的命令如下:

ALTER INDEX t1_c2_tableoid_idx REBUILD;

重建索引分区的命令如下:

ALTER INDEX t1_c1_idx REBUILD PARTITION p2_c1_idx;

判断分区表是否存在剪枝异常的场景

当分区表的分区键所在列存在条件时,可以触发分区剪枝。数据库会在优化器/执行器阶段识别到需要扫描的分区,而不会扫描全部分区。只有分区表的业务是顺序扫描,或者使用Local索引进行扫描时候,才可能触发分区剪枝;Global索引不会触发分区剪枝,这是因为Global索引是在整个分区表上创建的单个索引,不存在剪枝的概念。
剪枝是被动触发的,当查询业务满足分区剪枝条件时,会自动触发分区剪枝。

  • 判断是否触发了分区剪枝

可以通过查询计划来判断是否触发了分区剪枝。当扫描分区数少于分区总数时,即触发了分区剪枝。分区剪枝分为静态剪枝和动态剪枝,静态剪枝是指在优化器阶段就能识别到裁剪的分区;动态剪枝是指优化器阶段只能确定可以进行剪枝,但不知道具体裁剪到哪个分区,在执行器阶段才会确定裁剪的目标分区。
下面的业务触发了分区静态剪枝,计划中的'Iterations: 1'表示扫描了1个分区,'Selected Partitions: 1'表示扫描的目标分区下标是1。
这个下标是一个逻辑数组下标,对于范围分区/间隔分区,按照分区定义上界值升序排列;对于列表分区,按照第一个枚举值升序排列;对于哈希分区,按照计算后的哈希值升序排列。可以通过函数pg_get_tabledef获取分区定义,其列出的分区即为该对应下标。

gaussdb=# explain select * from t1 where c1 < 100; 
                              QUERY PLAN                                
----------------------------------------------------------------------- 
 Partition Iterator  (cost=0.00..27.86 rows=716 width=8) 
   Iterations: 1 
   ->  Partitioned Seq Scan on t1  (cost=0.00..27.86 rows=716 width=8) 
         Filter: (c1 < 100) 
         Selected Partitions:  1 
(5 rows)

下面的业务没有触发分区剪枝,计划中的'Iterations: 2'表示扫描了2个分区,'Selected Partitions: 1..2'表示扫描的目标分区下标是1和2。可以看到扫描的分区数等于分区表的总分区数,表示未进行任何分区剪枝。

gaussdb=# explain select * from t1; 
                               QUERY PLAN                                
------------------------------------------------------------------------ 
 Partition Iterator  (cost=0.00..31.49 rows=2149 width=8) 
   Iterations: 2 
   ->  Partitioned Seq Scan on t1  (cost=0.00..31.49 rows=2149 width=8) 
         Selected Partitions:  1..2 
(4 rows)

下面的业务触发了分区动态剪枝,计划中的'Iterations: PART'和'Selected Partitions: PART'表示优化器识别到分区表可以进行分区剪枝,但具体

gaussdb=# prepare p1 as select * from t1 where c1 < $1; 
gaussdb=# explain execute p1(100); 
                                         QUERY PLAN                                          
-------------------------------------------------------------------------------------------- 
 Partition Iterator  (cost=9.80..28.75 rows=716 width=8) 
   Iterations: PART 
   ->  Partitioned Bitmap Heap Scan on t1  (cost=9.80..28.75 rows=716 width=8) 
         Recheck Cond: (c1 < $1) 
         Selected Partitions:  PART 
         ->  Partitioned Bitmap Index Scan on t1_c1_idx  (cost=0.00..9.62 rows=716 width=0) 
               Index Cond: (c1 < $1) 
               Selected Partitions:  PART 
(8 rows)
  • 支持分区剪枝的场景

当分区键所在列存在条件时,可以进行分区剪枝。条件剪枝支持场景为:比较表达式(<,<=,=,>=,>)、逻辑表达式(AND、OR)、数组表达式。需要注意的是,列表和哈希分区不支持除等号外的其他比较表达式的剪枝。如果条件全为常量,则进行静态剪枝;如果条件带有参数、部分隐式转换、immutable函数,则进行动态剪枝。
当分区表作为参数化路径计划的内表且分区键所在列为索引检索条件时,支持动态剪枝。

  • 不支持分区剪枝的场景

分区键所在列的条件为子查询表达式、无法直接强转的类型转换、stable/volatile函数时,不支持分区剪枝。
分区表在生成除参数化路径外的其他JOIN计划时,不支持动态剪枝。

  • 业务改写适配分区剪枝

当业务设计不合理,导致原本逻辑上可以走分区剪枝的计划,最终未走分区剪枝时,可以改写业务以适配分区剪枝,从而提升分区表查询业务性能。比如使用HINT固定计划、在客户端修改绑参类型等方法。

标签:剪枝,GaussDB,查询,索引,分区表,c1,t1,分区
From: https://www.cnblogs.com/xxxmut/p/18571911

相关文章

  • GaussDB内存过载分析
    问题现象数据库进程内存占比较高长时间占比较高观察监控平台内存占用的变化曲线,无论当前数据库是否有业务在运行,数据库进程内存占总机器内存的比例长时间处于较高状态,且不下降。执行作业期间占比较高数据库进程在没有业务执行时,内存使用持续处于较低的状态,当有业务执行时,内......
  • GaussDB SQL调优:建立合适的索引
    ​背景GaussDB是华为公司倾力打造的自研企业级分布式关系型数据库,该产品具备企业级复杂事务混合负载能力,同时支持优异的分布式事务,同城跨AZ部署,数据0丢失,支持1000+扩展能力,PB级海量存储等企业级数据库特性。拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关......
  • 再识华为云数据库——GaussDB
    前言:华为云数据库GaussDB是一款拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关键能力,能为企业提供功能全面,稳定可靠,扩展性强,性能优越的企业级数据库服务。同时具有PB级海量数据存储、实时高效访问、自动化运维等特点,广泛应用于金融、电信、物流、电商、政......
  • 通过公网连接GaussDB数据库实例
    @目录1.通过公网连接GaussDB1.1实验介绍1.1.1关于本实验1.1.2实验目的1.2购买GaussDB数据库(可选)1.3公网IP绑定1.3.1购买弹性公网IP1.3.2绑定GaussDB数据库2附录一:安装和配置JDK2.1下载并安装JDK2.2配置JDK环境变量本实验概览图1.通过公网连接GaussDB1.1实验介绍......
  • GaussDB 数据库实验环境搭建指导
    @目录简介内容描述实验环境说明1GaussDB数据库购买1.1实验介绍1.1.1关于本实验1.1.2实验目的1.2购买GaussDB数据库1.2.1登录华为云1.2.2购买华为云GaussDB数据库简介本指导书适用于在华为云部署购买GaussDB数据库,通过该指导书可以顺利完成GaussDB数据库在华为云的购买。......
  • GaussDB数据类型转换介绍
    @目录一、数据类型转换场景二、数据类型转换及示例1、cast(valueAStype)2、to_date(text)3、to_date(text,format)4、to_char(datetime,format)5、to_char(string)6、CASE表达式三、小结一、数据类型转换场景数据类型转换在实际应用中非常常见。GaussDB作为一款企业级分布......
  • GaussDB数据库基础函数介绍-上
    ​目录一、函数在数据库中的作用二、GaussDB常用基础函数介绍与示例1、数字操作函数2、时间和日期处理函数3、类型转换函数4、数组函数5、范围函数6、窗口函数7、聚集函数8、安全函数9、系统信息函数10、动态脱敏函数.Tip:由于篇幅缘故,“5.范围函数、6.窗口函数、7.......
  • GaussDB数据类型介绍
    @目录一、GaussDB数据库二、数据类型概念及特点三、常用数据类型1、常用字符串类型介绍2、布尔类型3、数值类型4、日期/时间类型四、数据类型选择建议一、GaussDB数据库GaussDB是华为基于openGauss自研生态推出的云化企业级分布式关系型数据库,它支持多种数据类型,包括数值、字......
  • GaussDB数据库存储过程介绍
    @目录一、前言二、GaussDB中的定义三、存储过程的使用场景四、存储过程的使用优缺点五、存储过程的示例及示例解析1、GaussDB存储过程语法格式2、GaussDB存储过程语法示例3、存储过程的调用方法七、总结一、前言华为云数据库GaussDB是一款高性能、高安全性的云原生数据库,在数据......
  • GaussDB SQL基础语法示例-BOOLEAN表达式
    一、前言SQL是用于访问和处理数据库的标准计算机语言。GaussDB支持的SQL标准(默认支持SQL2、SQL3和SQL4的主要特性)。本系列将以《云数据库GaussDB—SQL参考》为主线进行介绍。二、GaussDBSQL中的BOOLEAN表达式介绍1、概念在GaussDB数据库中,BOOLEAN表达式是一种很常见的表达......