基于pg_qualstats和hypopg的自动索引调优
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的自动索引调优的更多相关文章
- OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- 11g新特性-自动sql调优(Automatic SQL Tuning)
11g新特性-自动sql调优(Automatic SQL Tuning) 在Oracle 10g中,引进了自动sql调优特性.此外,ADDM也会监控捕获高负载的sql语句. 在Oracle 11g中, ...
- SQL Server调优系列进阶篇(如何索引调优)
前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...
- SQL Server调优系列进阶篇 - 如何索引调优
前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...
- SQL Server 调优系列进阶篇 - 如何索引调优
前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...
- MySQL索引调优【转】
一.关于查询计划 其实,关于所有的关系型数据库中,在运行T-SQL语句的时候,在查询器进行编译运行的同时,都会有着自己的内部的一个优化过程,而这优化之后的产物就是:执行计划. 在SQL SERVER中 ...
- Mysql的索引调优详解:如何去创建索引以及避免索引失效
在正式介绍Mysql调优之前,先补充mysql的两种引擎 mysql逻辑分层 InnoDB:事务优先(适合高并发操作,行锁) MyISAM:性能优先(表锁) 查看使用的引擎: show variabl ...
- mysql数据库索引调优
一.mysql索引 1.磁盘文件结构 innodb引擎:frm格式文件存储表结构,ibd格式文件存储索引和数据. MyISAM引擎:frm格式文件存储表结构,MYI格式文件存储索引,MYD格式文件存储 ...
- 必读,sql加索引调优案例和explain extended说明
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 昨天分享了Mysql中的 explain 命令,使用 explain 来分析 select 语句的运行效果,如 :expl ...
随机推荐
- C++编译提示 default argument are given of parameter ..
如果定义一个类的构造函数时,带有默认的入参值,在cpp文件中实现构造函数时,是不能带的!否则就会提示该种类型的编译错误. //.h文件: namespace Ui { class Task; } cl ...
- git config命令详解
Git有一个工具被称为git config,它允许你获得和设置配置变量:这些变量可以控制Git的外观和操作的各个方面. 一. 配置文件的存储位置 这些变量可以被存储在三个不同的位置: 1./etc/ ...
- 【Docker】:全面认识Docker和基本指令
Docker逐渐成为虚拟化技术的佼佼者,接下来会推出一系列的Docker相关技术文章,Docker技术也是架构师的必备技能. 什么是Docker Docker 是一个开源的应用容器引擎,基于Go语言, ...
- 20191125:Python中的上下文管理机制with
20191125:with上下文管理 with是一个上下文管理器,用于执行代码块所需要的运行的时候的上下文入口和出口.上下文管理器的典型用法包括保存和还原各种全局状态,锁定和解锁资源,关闭打开的文件等 ...
- go context 源码分析
WithCancel func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { c := newCancelCtx(pare ...
- Spring AOP日志实现(一)
前置通知:获取访问的类,访问的方法,带参数和不带参数的 日志表信息描述字段: 获取访问时长:
- HTML 标签入门
HTML 简介 定义: 超文本标记语言(html)是标准通用标记语言下的一个应用,也是一种规范,一种标准 它通过标记符号来表示网页中的各个部分,网页文件本身是一种文本文件,通过在文本文件中添加标记符, ...
- linux管道和重定向
管道 管道应该是等左边的程序执行完,才使用左边的程序的输出执行右边的程序. 但是在测试的时候,如果左边的程序无限循环且不等待的输出,那么左边的程序执行时右边的程序也会执行,个人感觉这是linux的机制 ...
- 关于ubuntu软件图标的问题
原因是这样的,有一次我更新我的IDEA之后,程序图标就不见了. 怎么说呢,就是以下显示的这样. 在Frequent中显示正常, 在All中却没有!!! 是的,它就是在一边有一边没有... 奇了怪了. ...
- DNS服务——搭建企业内网DNS服务器的作用
前言 DNS服务——服务端 和 客户端 配置 介绍了如何在DNS安装DNS服务,更改一下配置文件就可以依据根提示解析全球域名.既然使用互联网上的DNS服务器就可以解析全球域名,为何还要自掏腰包搭建DN ...