pg-qualstats的安装和配置

1.安装pg-qualstats

sudo apt install postgresql--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- 

apt install postgresql--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 ;

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

  1. OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

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

    11g新特性-自动sql调优(Automatic SQL Tuning) 在Oracle 10g中,引进了自动sql调优特性.此外,ADDM也会监控捕获高负载的sql语句. 在Oracle 11g中, ...

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

    前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...

  4. SQL Server调优系列进阶篇 - 如何索引调优

    前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...

  5. SQL Server 调优系列进阶篇 - 如何索引调优

    前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...

  6. MySQL索引调优【转】

    一.关于查询计划 其实,关于所有的关系型数据库中,在运行T-SQL语句的时候,在查询器进行编译运行的同时,都会有着自己的内部的一个优化过程,而这优化之后的产物就是:执行计划. 在SQL SERVER中 ...

  7. Mysql的索引调优详解:如何去创建索引以及避免索引失效

    在正式介绍Mysql调优之前,先补充mysql的两种引擎 mysql逻辑分层 InnoDB:事务优先(适合高并发操作,行锁) MyISAM:性能优先(表锁) 查看使用的引擎: show variabl ...

  8. mysql数据库索引调优

    一.mysql索引 1.磁盘文件结构 innodb引擎:frm格式文件存储表结构,ibd格式文件存储索引和数据. MyISAM引擎:frm格式文件存储表结构,MYI格式文件存储索引,MYD格式文件存储 ...

  9. 必读,sql加索引调优案例和explain extended说明

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 昨天分享了Mysql中的 explain 命令,使用 explain 来分析 select 语句的运行效果,如 :expl ...

随机推荐

  1. clang, gcc, gdb

    Clang 比 GCC 编译器的优势: 1 编译速度更快 2 编译产出更小 3 出错提示更友好,比如 clang 在编译过程可以直接指出相对简单的出错位置以及它 " 认为 " 正确 ...

  2. Redis 的基本操作、Key的操作及命名规范

    Redis基本操作 查看数据的状态 pong redis 给我们返回 PONG,表示 redis 服务 运行正常 redis 默认用 使用 16 个 库 • Redis 默认使用 16 个库,从 0 ...

  3. 生成ftp文件的目录树

    依赖 <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</a ...

  4. SQLSERVER查询存储过程内容

    --使用语句查看一个存储过程的定义 EXEC sp_helptext 'Auth_BankCardAuthorize' --查询所有存储过程的名称以及定义 SELECT name, definitio ...

  5. mdk编译时的内存分析

    内存四区(代码区,全局区,栈区,堆区) Code:即代码域,它指的是编译器生成的机器指令,这些内容被存储到ROM区. RO-data:Read Only data,即只读数据域,它指程序中用到的只读数 ...

  6. 基于NetCore+SqlSugar+Layui开发出来的开源框架项目FytSoaCms问题处理

    最近刚好在学习NetCore框架所以就在网上搜索了一下相关的开源框架项目,正好在Github上找到了一个不错的开源框架所以推荐给大家看看哈哈哈. 1:项目相关技术 运行NetCore SDK版本为2. ...

  7. 字符串replace的理解和练习和配合正则表达式的使用

    下面代码展示了(demo地址 https://codepen.io/peach_/pen/jONJjRY): 1.字符串replace的理解和练习和配合正则表达式的使用, 2.正则表达式学习 3.通过 ...

  8. centos6克隆虚拟机后,网络无法访问和启动

    使用vmware安装centos6虚拟机时, 克隆虚拟机后无法访问网络. 原因是:产生了重复的网卡信息** 克隆后在70-persistent-net.rules文件中会多一行网卡信息,把第一行网卡信 ...

  9. 关于MQ的几件小事(三)如何保证消息不重复消费

    1.幂等性 幂等(idempotent.idempotence)是一个数学与计算机学概念,常见于抽象代数中. 在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同.幂等函数,或 ...

  10. oracle 01741:非法的零长度标识

    转自:https://blog.csdn.net/wanderball/article/details/7690206 出现此问题是标识符里有两个连续的“”号,去掉即可,或是里面填充内容,避免两个连续 ...