PostgreSQL SQL自动优化案例 - 极简,自动推荐索引

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介:

标签

PostgreSQL , 自动推荐索引 , 统计信息 , 慢SQL回溯 , TOP SQL , TOP SQL


背景

SQL自动优化是数据库的高级特性,其中包括SQL 自动rewrite,自动推荐索引,自动优化执行计划 等。

1、自动优化执行计划

目前postgrespro在做这块

https://postgrespro.com/roadmap/56513

Machine learning

Query planner selects “cheapest” query plan based on its cost estimation. But it’s done with many rough assumptions. This is why the estimated cost could be inadequate to real execution cost. One possibility is to improve the cost estimate mechanism itself by adding features like multivariate statistics. Another possibility is to use query execution feedback: see how estimated parameter values differ from actual parameter values. We can apply machine learning techniques to improve the cost estimates using this feedback, so DBMS would learn on its own mistakes.

We’ve already done this in a simple case, and further work is planned in the following directions:

  • Extend implemented model to cover more use cases,

  • Provide the infrastructure necessary to make our machine learning an extension.

Execution-time planning

Currently, query planning strictly precedes query execution. Sometimes it appears to be a serious limitation. When one part of a plan is already executed it could be possible to significantly improve the rest of the plan on the basis of gathered statistics. We can see two cases when this approach could be applied:

  • Online reordering of filter expressions. During sequential scan of large table it’s important to do the cheapest and the most selective checks first. However estimated selectivity and cost of filtering are inaccurate, and thus the order of applying filters based on estimates can be not optimal. But filter expressions could be reordered online on the base of statistics of their previous execution.

  • Some queries could be divided into sequence of steps when subsequent steps could be replanned on the base of results of previous steps. For instance, suppose that step 1 is a scan of table A, and step 2 is a join of tables A and B. Depending on row count and data distribution from the first step we could choose different join algorithm on the second step.

2、自动rewrite SQL,实际上PostgreSQL已经做了很多这样的工作,不过还有更多可以做的。这里有一些例子。

《PostgreSQL 优化器逻辑推理能力 源码解析》

3、自动推荐索引,就是本文要说的。

EDB已支持:https://www.enterprisedb.com/docs/en/9.5/asguide/EDB_Postgres_Advanced_Server_Guide.1.56.html

自动推荐索引的方法

1、首先要判断哪些表可能需要加索引,方法如下:

1.1、TOP SQL与慢SQL,可以从pg_stat_statements中获取。

慢 SQL还可以从日志中获取。

参考:

《PostgreSQL 如何查找TOP SQL (例如IO消耗最高的SQL)》

1.2、统计信息

从统计信息中,同样可以分析出哪些表可能需要加索引。

《PostgreSQL pg_stat_ pg_statio_ 统计信息(scan,read,fetch,hit)源码解读》

分析方法如下,

A=pg_stat_all_tables.seq_scan,代表全表扫描次数   
   
B=pg_stat_all_tables.seq_tup_read,代表返回记录数   
   
C=pg_class.reltuples,代表表的记录数   
   
D=pg_class.relpages,代表表的大小(占用了多少数据块)   
   
E=pg_statio_all_tables.heap_blks_read + pg_statio_all_tables.heap_blks_hit,代表扫描了多少个堆表的数据块   

如果A很大,并且B/A很小,并且C较大或D较大,那么说明需要加索引。

如果E/A较大,并且D或C较大,那么说明需要加索引。

判断标准就是:

大表被全表扫描了很多数据块,并返回了少量记录。

1.3、针对需要加索引的表,在pg_stat_statements中,找到对应的SQL。

2、判断需要针对哪些列加索引

针对找到的需要加索引的SQL,生成执行计划。

从执行计划中,判断哪些位置的COST较大,并且是SEQUENCE SCAN,找到对应的filter字段。

3、判断需要加什么类型的索引(btree, brin, gin, gist, sp-gist, hash, bloom, ...?)

对2得到的字段,判断应该加什么类型的索引?原理如下,根据统计信息,以及索引接口的特性,自动判断加什么类型的索引:

《自动选择正确索引访问接口(btree,hash,gin,gist,sp-gist,brin,bitmap...)的方法》

《PostgreSQL 9种索引的原理和应用场景》

4、记录慢SQL执行计划

记录第2步骤得到的执行计划。

5、加虚拟索引

虚拟索引,并不是针对索引,不会影响实际的执行计划,也不耗资源,方法如下:

《PostgreSQL 虚拟|虚假 索引(hypothetical index) - HypoPG》

6、查看加完索引后慢SQL执行计划是否发生变化。

使用虚拟索引生成执行计划,并对比4得到的执行计划,是否用上了索引。

方法如下:

《PostgreSQL 虚拟|虚假 索引(hypothetical index) - HypoPG》

7、输出报告

输出两个执行计划的前后对比,输出报告。

8、删除虚拟索引

9、加真实索引

用户可以查看报告,并决定是否加索引。

加索引时,可以使用并行语法,不堵塞DML操作。

Command:     CREATE INDEX   
Description: define a new index   
Syntax:   
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON table_name [ USING method ]   
    ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )   
    [ WITH ( storage_parameter = value [, ... ] ) ]   
    [ TABLESPACE tablespace_name ]   
    [ WHERE predicate ]   

参考

《自动选择正确索引访问接口(btree,hash,gin,gist,sp-gist,brin,bitmap...)的方法》

《PostgreSQL 9种索引的原理和应用场景》

《PostgreSQL 函数调试、诊断、优化 & auto_explain》

《PostgreSQL 统计信息pg_statistic格式及导入导出dump_stat - 兼容Oracle》

《PostgreSQL pg_stat_ pg_statio_ 统计信息(scan,read,fetch,hit)源码解读》

《PostgreSQL 如何查找TOP SQL (例如IO消耗最高的SQL)》

《如何追溯 PostgreSQL 慢查询当时的状态》

《PostgreSQL 虚拟|虚假 索引(hypothetical index) - HypoPG》

《PostgreSQL 优化器逻辑推理能力 源码解析》

https://postgrespro.com/roadmap/56513

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
2月前
|
SQL Oracle 关系型数据库
SQL优化-使用联合索引和函数索引
在一次例行巡检中,发现一条使用 `to_char` 函数将日期转换为字符串的 SQL 语句 CPU 利用率很高。为了优化该语句,首先分析了 where 条件中各列的选择性,并创建了不同类型的索引,包括普通索引、函数索引和虚拟列索引。通过对比不同索引的执行计划,最终确定了使用复合索引(包含函数表达式)能够显著降低查询成本,提高执行效率。
|
2月前
|
SQL 关系型数据库 MySQL
如何确认SQL用了索引:详细技巧与方法
在数据库管理中,索引是提高SQL查询性能的重要手段
|
2月前
|
SQL 存储 关系型数据库
SQL默认索引是什么:深入解析与技巧
在SQL数据库中,索引是一种用于提高查询性能的重要数据结构
|
2月前
|
SQL 存储 关系型数据库
SQL默认索引是什么
在SQL数据库中,索引是一种用于提高查询性能的数据结构
|
2月前
|
SQL 关系型数据库 MySQL
如何确认SQL用了索引
在数据库管理和优化过程中,确认SQL查询是否使用了索引是一个至关重要的步骤
|
2月前
|
SQL 大数据 API
大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例
大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例
47 0
|
2月前
|
SQL 关系型数据库 MySQL
如何确认SQL查询是否使用了索引:详细步骤与技巧
在数据库管理和优化中,确认SQL查询是否有效利用了索引是提升性能的关键步骤
|
2月前
|
索引
SQL_创建和管理索引
SQL_创建和管理索引
28 0
|
关系型数据库 分布式数据库 PolarDB
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
366 0
|
存储 缓存 关系型数据库

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版