基于pg_qualstats和hypopg的自动索引调优

pg-qualstats的安装和配置

1.安装pg-qualstats

sudo apt install postgresql-10-pg-qualstats

2.将pg_qualstats和pg_stat_statements添加到shared_preload_libraries,使得postgresql .conf文件中具有以下设置:

#shared_preload_libraries = ‘pg_stat_statements,pg_qualstats‘ # (change requires restart)

postgresql.conf文件在/etc/postgresql/10/main/目录下

执行grep ‘shared_preload‘ postgresql.conf可见

3.重新启动PG。

service postgresql restart

4.进入PG

sudo su - postgres

psql

5.查询shared_preload_libraries

show shared_preload_libraries ;

Hypopg的安装和配置

1.安装 hypopg

apt install postgresql-server-dev-10 

apt install postgresql-10-hypopg

自动索引调优

1.进入PG

sudo su - postgres

2.设置采样率 pg_qualstats .sample_rate1,保证调参涉及到所有的query

psql -d postgres -c "ALTER SYSTEM SET pg_qualstats.sample_rate TO 1"

验证

psql -c "select pg_reload_conf()"

3.进入PG

psql

4.加载extension

CREATE EXTENSION hypopg;

CREATE EXTENSION pg_stat_statements ;

CREATE EXTENSION pg_qualstats;

5.查看配置

\dx

show shared_preload_libraries ;

6.建立测试数据库

create database testdb owner postgres;

7.复现样例测试

建表

CREATE TABLE test (id int, dept int, id2 int, id3 int, id4 int, id5 int,id6 int,id7 int,details text, zipcode int);

插入数据

INSERT INTO test SELECT (random() * 1000000)::int, (random() * 1000000)::int, (random() * 1000000)::int,(random() * 1000000)::int,(random() * 1000000)::int,(random() * 1000000)::int,(random() * 1000000)::int,(random() * 1000000)::int,

md5(g::text), floor(random()* (20000-9999 + 1) + 9999)

FROM generate_series(1,1*1e6) g;

执行workload

select * from test where id2 = 1 and id4 = 3;

select * from test where id3 = 3;

select * from test where id3 = 3 and id4 = 2;

select * from test where id4 = 2 and id2 = 3;

建立函数 find_usable_indexes

CREATE OR REPLACE FUNCTION find_usable_indexes()

RETURNS VOID AS

$$

DECLARE

    l_queries     record;

    l_querytext     text;

    l_idx_def       text;

    l_bef_exp       text;

    l_after_exp     text;

    hypo_idx      record;

    l_attr        record;

    /* l_err       int; */

BEGIN

    CREATE TABLE IF NOT EXISTS public.idx_recommendations (queryid bigint,

    query text, current_plan jsonb, recmnded_index text, hypo_plan jsonb);

    FOR l_queries IN

    SELECT t.relid, t.relname, t.queryid, t.attnames, t.attnums,

    pg_qualstats_example_query(t.queryid) as query

      FROM

        (

         SELECT qs.relid::regclass AS relname, qs.relid AS relid, qs.queryid,

         string_agg(DISTINCT attnames.attnames,‘,‘) AS attnames, qs.attnums

         FROM pg_qualstats_all qs

         JOIN pg_qualstats q ON q.queryid = qs.queryid

         JOIN pg_stat_statements ps ON q.queryid = ps.queryid

         JOIN pg_amop amop ON amop.amopopr = qs.opno

         JOIN pg_am ON amop.amopmethod = pg_am.oid,

         LATERAL

              (

               SELECT pg_attribute.attname AS attnames

               FROM pg_attribute

               JOIN unnest(qs.attnums) a(a) ON a.a = pg_attribute.attnum

               AND pg_attribute.attrelid = qs.relid

               ORDER BY pg_attribute.attnum) attnames,     

         LATERAL unnest(qs.attnums) attnum(attnum)

               WHERE NOT

               (

                EXISTS

                      (

                       SELECT 1

                       FROM pg_index i

                       WHERE i.indrelid = qs.relid AND

                       (arraycontains((i.indkey::integer[])[0:array_length(qs.attnums, 1) - 1],

                        qs.attnums::integer[]) OR arraycontains(qs.attnums::integer[],

                        (i.indkey::integer[])[0:array_length(i.indkey, 1) + 1]) AND i.indisunique)))

                       GROUP BY qs.relid, qs.queryid, qs.qualnodeid, qs.attnums) t

                       GROUP BY t.relid, t.relname, t.queryid, t.attnames, t.attnums                   

    LOOP

        /* RAISE NOTICE ‘% : is queryid‘,l_queries.queryid; */

        execute ‘explain (FORMAT JSON) ‘||l_queries.query INTO l_bef_exp;

        execute ‘select hypopg_reset()‘;

        execute ‘SELECT indexrelid,indexname FROM hypopg_create_index(‘‘CREATE INDEX on ‘||l_queries.relname||‘(‘||l_queries.attnames||‘)‘‘)‘ INTO hypo_idx;      

        execute ‘explain (FORMAT JSON) ‘||l_queries.query INTO l_after_exp;

        execute ‘select hypopg_get_indexdef(‘||hypo_idx.indexrelid||‘)‘ INTO l_idx_def;

        INSERT INTO public.idx_recommendations (queryid,query,current_plan,recmnded_index,hypo_plan)

        VALUES (l_queries.queryid,l_querytext,l_bef_exp::jsonb,l_idx_def,l_after_exp::jsonb);        

    END LOOP;    

        execute ‘select hypopg_reset()‘;

END;

$$ LANGUAGE plpgsql;

执行函数find_usable_indexes

select find_usable_indexes();

查找索引

select queryid, current_plan->0->‘Plan‘->>‘Total Cost‘ as "cost_without_index",

hypo_plan->0->‘Plan‘->>‘Total Cost‘ as "cost_with_index",

round((((current_plan->0->‘Plan‘->>‘Total Cost‘)::numeric-(hypo_plan->0->‘Plan‘->>‘Total Cost‘)::numeric)*100/(current_plan->0->‘Plan‘->>‘Total Cost‘)::numeric),2) as percent_improvd

FROM idx_recommendations order by 4 desc;
select b.query, a.recmnded_index,round((((a.current_plan->0->‘Plan‘->>‘Total Cost‘)::numeric-(hypo_plan->0->‘Plan‘->>‘Total Cost‘)::numeric)*100/(a.current_plan->0->‘Plan‘->>‘Total Cost‘)::numeric),2) as percent_improvd FROM idx_recommendations a JOIN pg_stat_statements b ON a.queryid = b.queryid WHERE round((((current_plan->0->‘Plan‘->>‘Total Cost‘)::numeric-(hypo_plan->0->‘Plan‘->>‘Total Cost‘)::numeric)*100/(current_plan->0->‘Plan‘->>‘Total Cost‘)::numeric),2) > 0 order by 3 desc ;

原文地址:https://www.cnblogs.com/xueqiuqiu/p/11805033.html

时间: 2024-10-17 23:53:20

基于pg_qualstats和hypopg的自动索引调优的相关文章

数据类型与索引调优全解析

MySQL架构优化实战系列1:数据类型与索引调优全解析 原创 2016-06-08 汤抗 DBAplus社群 一.数据类型优化 数据类型 整数   数字类型:整数和实数 tinyint(8).smallint(16).mediuint(24).int(32).bigint(64) 数字表示对应最大存储位数,如 tinyint (-127 --- 128),tinyint unsigned 表示不允许负数,则范围为 (0 -- 255). 常规数据库中 int(11) 只是表示控制显示字符的个数是

11g新特性-自动sql调优(Automatic SQL Tuning)

11g新特性-自动sql调优(Automatic SQL Tuning) 在Oracle 10g中,引进了自动sql调优特性.此外,ADDM也会监控捕获高负载的sql语句. 在Oracle 11g中,通过运行sql tuning advisor加强了自动sql调优功能.默认情况下是每天夜间通过自动任务的方式运行"自动sql调优". 自动sql调优的过程: 1.识别需要调优的sql语句  根据AWR中的CPU和I/O负载来识别 2.调优,生成新的sql profile 在维护窗口(mai

SQL Server调优系列进阶篇(如何索引调优)

前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本篇我们就开始分析这块内容,关于索引的基础知识就不打算深入分析了,网上一搜一片片的,本篇更侧重的是一些实战项内容展示,希望通过本篇文章各位看官能在真正的场景中找到合适的解决方法足以. 对于索引的使用,我希望的是遇到问题找到合适的解决方法就可以,切勿乱用!!! 本篇在分析出索引的优越性的同时也将负面影响

数据库索引调优

一.索引 1.索引类型 普通索引:无任何限制的索引 唯一索引:列值唯一的索引,可以为空值 主键索引:表的主键,特殊的唯一性索引,不能为空值 组合索引:多个字段上的索引,遵循左前缀集合 全文索引:来查找文本中的关键字 2.使用explain+sql语句进行调优 (1)explain包含的信息包含: 主要从id.type.key.rows.Extra分析 (2)id 表示执行的先后顺序,id值大的先执行,小的后执行,id值相同的从上到下执行 (3)type 访问类型,结果值从好到坏依次是:syste

MySQL架构优化实战系列1:数据类型与索引调优全解析

一.数据类型优化 数据类型 整数   数字类型:整数和实数 tinyint(8).smallint(16).mediuint(24).int(32).bigint(64) 数字表示对应最大存储位数,如 tinyint (-127 --- 128),tinyint unsigned 表示不允许负数,则范围为 (0 -- 255). 常规数据库中 int(11) 只是表示控制显示字符的个数是11个,int(1) 和 int(20) 存储和计算是一样的,即 int(1) 照样可以存储1111(4位数)

索引调优

?选择正确的存储引擎. 主键不可过长,因为辅助索引都会引用主索引.(主键的选择) 合适的索引列的顺序. B+树:局部性,磁盘预读. InnoDB聚集索引:数据文件本身就是索引文件. “最左前缀原理” 联合索引,查询优化器自动调整. 避免表达式出现在索引语句. 索引避免NULL. 索引越小越简单地类型.

SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)

前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲言少叙,进入本篇的内容. 技术准备 数据库版本为SQL Server2012,利用微软的以前的案例库(Northwind)进行分析,部分内容也会应用微软的另一个案例库AdventureWorks. 相信了解SQL Server的朋友,对这两个库都不会太陌生. 一.并行Hint提示 (MAXDOP N

SQL Server调优系列进阶篇(如何维护数据库索引)

原文:SQL Server调优系列进阶篇(如何维护数据库索引) 前言 上一篇我们研究了如何利用索引在数据库里面调优,简要的介绍了索引的原理,更重要的分析了如何选择索引以及索引的利弊项,有兴趣的可以点击查看. 本篇延续上一篇的内容,继续分析索引这块,侧重索引项的日常维护以及一些注意事项等. 闲言少叙,进入本篇的主题. 技术准备 数据库版本为SQL Server2012,前几篇文章用的是SQL Server2008RT,内容区别不大,利用微软的以前的案例库(Northwind)进行分析,部分内容也会

SQL自动调优

SQL自动调优,是oracle 自带的调优工具,可以提出一些解决方案. 本次我主要介绍下面这些自动SQL调优工具: 自动SQL调优(automatic sql tuning) SQL调优工具集(SQL tuning sets,STS) SQL调优顾问(SQL Tuning Advisor) 自动数据库诊断监视器(addm) 显示SQL自动调优建议最快的方法: SQL> select dbms_auto_sqltune.report_auto_tuning_task from dual; GENE