前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Postgresql INDEX HOT 原理与更好的 “玩转” INDEX

Postgresql INDEX HOT 原理与更好的 “玩转” INDEX

作者头像
AustinDatabases
发布于 2023-02-26 03:09:16
发布于 2023-02-26 03:09:16
1.2K0
举报
文章被收录于专栏:AustinDatabasesAustinDatabases

好长时间不进行研究了,最近被突发的问题想到了INDEX 的问题,随机想到数据和INDEX 存储在一起会怎样,我们将索引和数据进行分离后,会不会对数据库的性能有优化的可能。

所以让我想到了 HOT heap only tuples 这个事情,但是在是记不清了,所以就的翻翻旧账了。

首先HOT ,heap only tuples 是Postgres 用户用于减少基于UPDATE 后的大量的IO 所做的工作,主要的问题就是在MVCC 导致的UPDATE 等于INSERT + 废弃行,以及新插入的行都需要对当前的索引负责。

相对于表本身需要VACUUM 和 AUTOVACUUM 的情况下,我们的其实需要更多的I/O 工作在针对这些操作针对索引的问题的IO消耗,因为索引需要修改指针到新的行。

Postgres 为了降低指针重新指向的问题,提出在一个行UPDATE后,就在原有的位置上插入他的新的版本的行,通过这样的方式让索引知道新的行就在老得行的下一个位置,避免大量的更新索引的操作,使用这样的方式就可以在索引上直接指向原来的位置的下一个位置。

而要完成这个事情,需要一个特殊的条件就是,更新的列不能是当前的索引列。

下面是经典的两个图 ,1 如果没有 HOT 的情况下 2 使用HOT 的情况

所以结论是POSTGRESQL 在频繁的UPDATE 当中,如果更新的字段是索引的情况下,将引发大量的索引更新,引起IO的消耗的情况。

在POSTGRESQL 有这样的问题的情况下,我们需要针对POSTGRESQL 的索引更加的小心和谨慎。

所以我们需要注意以下的问题

1 unused indexes 无用的索引

2 bloated indexes 膨胀的索引

3 Duplicate and invalid index 重复的索引

为什么会产生以上的这些问题呢

1 添加索引是在业务确认之前添加的,也就是添加索引并不是完全确认了业务的情况下进行的。

2 添加的索引针对的业务下线了

3 服务器的资源提升了,增加了,暂时不使用索引可以达到更好的

4 业务发展,后期添加的索引替代了早期的索引

5 操作失误,建立了同样的索引

那么针对以上的问题,我们需要

1 找到无用的索引

SELECT s.schemaname,

s.relname AS tablename,

s.indexrelname AS indexname,

pg_relation_size(s.indexrelid) AS index_size

FROM pg_catalog.pg_stat_user_indexes s

JOIN pg_catalog.pg_index i ON s.indexrelid = i.indexrelid

WHERE s.idx_scan = 0

AND 0 <>ALL (i.indkey)

AND NOT i.indisunique

AND NOT EXISTS

(SELECT 1 FROM pg_catalog.pg_constraint c

WHERE c.conindid = s.indexrelid)

ORDER BY pg_relation_size(s.indexrelid) DESC;

这里的无用的索引的问题,在通过语句找出相关得信息,只能作为一个借鉴的值,而不是一个可以完全借鉴的值。

得到这些信息,只能是还需要更多的分析,才能将这些索引清理掉。

2 索引的碎片率的问题,导致索引的性能的问题 ,基于POSTGRESQL MVCC 以及相关的问题,导致表膨胀,这样的情况下,也会导致索引碎片的问题,所以发现并重建索引是一个需要注意的问题。

create extension pgstattuple;

SELECT i.indexrelid::regclass,

s.leaf_fragmentation

FROM pg_index AS i

JOIN pg_class AS t ON i.indexrelid = t.oid

JOIN pg_opclass AS opc ON i.indclass[0] = opc.oid

JOIN pg_am ON opc.opcmethod = pg_am.oid

CROSS JOIN LATERAL pgstatindex(i.indexrelid) AS s

WHERE t.relkind = 'i'

AND pg_am.amname = 'btree' and s.leaf_fragmentation > 0 and s.leaf_fragmentation <> 'NaN';

通过上面的语句去查询你索引的碎片率,通过这个来决定你的是否要进行索引的重建的工作。

3 重复索引的问题

基于上面的问题,索引不使用另外一种可能是有同类的索引,所以在发现索引不被使用的情况下,可以先看看是否有重复的索引的原因引起的,重复索引的害处可谓是“罄竹难书”

1 众所周知的重复索引,引起插入效率低

2 重复索引导致的数据量加大的问题

3 进行VACUUM AUTOVACUUM 多余的重复索引导致的操作时间和资源消耗过大的问题。

所以重复索引的问题一定要将多余的索引清理出去

SELECT indrelid::regclass table_name,

att.attname column_name,

amname index_method

FROM pg_index i,

pg_class c,

pg_opclass o,

pg_am a,

pg_attribute att

WHERE o.oid = ALL (indclass)

AND att.attnum = ANY(i.indkey)

AND a.oid = o.opcmethod

AND att.attrelid = c.oid

AND c.oid = i.indrelid

GROUP BY table_name,

att.attname,

indclass,

amname, indkey

HAVING count(*) > 1;

SELECT indrelid::regclass AS TableName ,array_agg(indexrelid::regclass) AS Indexes

FROM pg_index

GROUP BY indrelid ,indkey

HAVING COUNT(*) > 1;

通过上面的语句来查看当前的数据库中是否有重复的索引。

除此以外,我们还可以针对索引做如下的一些工作

1 在Postgresql 中创建针对索引的表空间,数据和索引进行分离,而不要将索引和数据创建在一个数据文件内。

postgres=# create tablespace index_storage location '/pgdata/index';

CREATE TABLESPACE

postgres=# create index idx_user_name on user_ini(user_name) tablespace index_storage;

CREATE INDEX

postgres=#

2 针对当前的索引进行查询和分析

1 针对当前有多少索引进行信息的获取

SELECT CONCAT(n.nspname,'.', c.relname) AS table,i.relname AS index_name,x.indisunique as is_unique FROM pg_class c

INNER JOIN pg_index x ON c.oid = x.indrelid

INNER JOIN pg_class i ON i.oid = x.indexrelid LEFT JOIN pg_namespace n ON n.oid = c.relnamespace

WHERE c.relkind = ANY (ARRAY['r', 't']) and c.relname not like 'pg%';

2 这对当前的索引的大小进行分析

SELECT

relname AS objectname,

relkind AS objecttype,

reltuples :: bigint AS "rows",

pg_size_pretty(relpages::bigint*8*1024) AS size

FROM pg_catalog.pg_class where relkind = 'i'

ORDER BY relpages DESC;

3 针对索引使用的次数进行统计,如每天索引被使用多少次,如果索引组最近一段时间使用的频次明显比之前要少,或者根本就不使用了,就需要分析有没有可能是因为索引损坏造成的问题。

SELECT s.relname AS table_name,

indexrelname AS index_name,

i.indisunique,

idx_scan AS index_scans

FROM pg_catalog.pg_stat_user_indexes s,

pg_index i

WHERE i.indexrelid = s.indexrelid;

另外,在索引的工作中,还有一些问题基于索引的损坏导致的问题,会发现如下的一些问题

1 本来有索引但是在查询中不走索引而是走全表扫描

2 通过 pg_stat_user_tables 表中的 seq_scan 和 idx_scan 两个字段的数值的对比来发现问题,如 seq_scan 疯狂的增加数字,而idx_scan 里面不增长或增长很慢,(1 是否有对应的索引 2 索引是否损坏)

3 在查询中出现错误的数据,如查询范围的明显标定的很清楚,但是查询的数据突破了这个范围,也就是查询的值不对。

以上的方式也可能是其他问题造成的,如数据库表的analyze 操作不及时,导致统计分析的数据出现偏差造成的。

基于以上的一些内容,索引的维护和信息的收集,以及问题的发现对于索引的维护是非常重要的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PostgreSQL集群篇——常用的运维SQL
本文主要是我日常使用的一些运维SQL和整理于互联网上的SQL,为了方便日常的使用,特把其汇总起来,遇到常用的时将会进行补充该文,欢迎大家在评论区进行提出一些常用的SQL。
cn華少
2021/11/24
1.3K0
PostgreSQL 如何对索引进行分析和处理
最近有人私信问POSTGRESQL 怎么比MYSQL的索引大,这个问题升级上我个人觉得从这几点考虑
AustinDatabases
2023/09/06
3580
PostgreSQL 如何对索引进行分析和处理
PostgreSql Postgresql 监控你说了不算,谁说了算 ? (5 整理的一些脚本)
一写就写到了第五期,有点写连续剧的味道,可能会有第六期,我想是,今天的内容并不是某些工具,其实工具也是根据数据库的原理,通过各种方式获得数据。那怎么通过PG中的系统表来获得数据就是这期的重点。
AustinDatabases
2020/07/16
7300
PostgreSql  Postgresql 监控你说了不算,谁说了算 ? (5  整理的一些脚本)
史上最全:PostgreSQL DBA常用SQL查询语句(建议收藏学习)
查看帮助命令本周六,在北京将迎来一年一度的 ACOUG年会,在本次年会上,我们将对社区过去一年的工作进行回顾和梳理,并展望和探讨下一年工作的内容,同时,本次年会也开放了直播通道,名额不多,报名从速哦~
数据和云
2019/12/24
10.9K0
MogDB/openGauss 故障排查思路
当我们收到反馈说数据库响应慢或者压测过程中数据库有报错,第一步先收集数据库服务器资源使用情况,这一步是处理所有故障的前提。
数据和云
2021/10/13
1.1K0
数据库PostrageSQL-判断磁盘用量
每个表都有一个主要的堆磁盘文件,大多数数据都存储在其中。如果一个表有着可能会很宽(尺寸大)的列, 则另外还有一个TOAST文件与这个表相关联, 它用于存储因为太宽而不能存储在主表里面的值(参阅Section 68.2)。如果有这个附属文件,那么TOAST表上会有一个可用的索引。 当然,同时还可能有索引和基表关联。每个表和索引都存放在单独的磁盘文件里 — 如果文件超过 1G 字节,甚至可能多于一个文件。这些文件的命名原则在Section 68.1中描述。
cwl_java
2021/01/13
4760
PostgreSql 怎么获取数据库中关键系统信息(一)
如何通过SQL 的方式获得数据库中的一些关键信息,是一个DB最正常的工作,如何通过一些SQL来获得PG的一些关键的参数和信息或者是数据库中的一些信息是需要知道的一件事情。以下是部分 1
AustinDatabases
2020/09/27
1.2K0
PostgreSQL 扫盲贴 常用的监控分析脚本
我一直有一个错觉,大家的POSTGRESQL的技术都非常了得,在年前实际上对我有几次的感触。
AustinDatabases
2025/03/03
1050
PostgreSQL 扫盲贴 常用的监控分析脚本
PgSQL技术内幕-Analyze做的那些事-pg_stat_all_tables
PgSQL技术内幕-Analyze做的那些事-pg_stat_all_tables
yzsDBA
2023/11/27
5410
PgSQL技术内幕-Analyze做的那些事-pg_stat_all_tables
Postgresql 损坏的索引怎么查出来,解决了他
POSTGRESQL 中如果你的表文件有损坏,则在查询中会直接告诉你某些文件缺失,你无法对这个表进行查询,或操作. 如果是索引可能就没有这么的简单了.
AustinDatabases
2021/04/01
1.1K0
Postgresql常用运维指令记录
最近偶尔需要处理一些客户问题,这里记录更新下常用命令 OS tcpdump -i eth0 -s 0 -w s2_s.cap port 3006 strace -T -tt -e trace=all -p 21231 strace -T -tt -e trace=all -o file -p 21231 perf top --call-graph=fp --dsos=/data01/bin/pg1017/bin/postgres # Sample on-CPU functions for
mingjie
2022/05/12
7260
30个实用SQL语句,玩转PostgreSQL
PostgreSQL是一款功能非常强大的开源关系型数据库,它支持哈希索引、反向索引、部分索引、Expression 索引、GiST、GIN等多种索引模式,同时可安装功能丰富的扩展包。相较于Mysql,PostgreSQ支持通过PostGIS扩展支持地理空间数据、支持嵌套循环,哈希连接,排序合并三种表连接方式等一系列的强化功能。本文主要整理总结了30个实用SQL,方便大家可以高效利用PostgreSQL。
慕枫技术笔记
2023/03/20
7820
30个实用SQL语句,玩转PostgreSQL
程序员硬核“年终大扫除”,清理了数据库 70GB 空间
【导语】春节将至,俗话说“腊月二十四,掸尘扫房子”,很多人会在腊月二十四给家里做大扫除迎新春。
AI科技大本营
2021/02/05
2.3K0
Postgresql system Catalog 中的系统表能告诉你什么 (二)?
接上期,postgresql 的system catalog 中包含了不少系统表,
AustinDatabases
2021/04/01
7130
Postgresql源码(52)bitmapset分析RelationGetIndexAttrBitmap
RelationGetIndexAttrBitmap可以返回四个bitmapset标识所有索引的位置,位置全部加过偏移量(7)。
mingjie
2022/05/31
3750
PostgreSQL pg_dump 原理探究与备份数据一致性问题和备份注意事项 与 PG MYSQL 到底谁是NO.1
我其实是想郑重其事的回答以下在上个礼拜分享会分享后,一个人最后对我的一个问题,问题是, PG 和 MYSQL 到底那个是 NO.1 ,当时我的语气不是很好,因为我觉得很无聊,在此表示道歉,但观点我是不变的。
AustinDatabases
2024/01/04
4901
PostgreSQL  pg_dump 原理探究与备份数据一致性问题和备份注意事项 与  PG MYSQL 到底谁是NO.1
PostgreSQL 读书会 一期 系统目录表 1
最近经历了一些事情,貌似也更深层的懂得了一些之前就“懂得”的道理,也理解了之前一些不能理解的人和事。最近也反思之前所做的一切,其实都和爱有关,乔布斯曾经说过,如果你爱他,你能更深层次的切入,因为任何一件事情如果想深层次的理解,都和你爱不爱他有关,越往深层次去做,越枯燥,越难受,只有你爱了他,才能继续走下去。 这也是为什么大部分“混社会”的人都只能叫,从业者,而不是专家的原因之一吧。
AustinDatabases
2020/06/23
4410
Prometheus+Grafana PG监控部署以及自定义监控指标
Prometheus:是从云原生计算基金会(CNCF)毕业的项目。Prometheus是Google监控系统BorgMon类似实现的开源版,整套系统由监控服务、告警服务、时序数据库等几个部分,及周边生态的各种指标收集器(Exporter)组成,是在当下主流的监控告警系统。
数据和云
2021/08/27
4.4K0
Prometheus+Grafana PG监控部署以及自定义监控指标
综合指南:postgresql shared buffers
本文主要针对下面问题详述PG的共享内存:PG中需要给共享内存分配多少内存?为什么?
yzsDBA
2021/01/05
1.6K0
综合指南:postgresql shared buffers
Greenplum查看psql操作执行的具体语句
有时候,这可以作为一种参考的方向,查看psql命令行如何获取结果。 我们在用psql登陆时,增加-E选项即可,示例如下: postgres=# \d+ test_table ********* QUERY ********** SELECT c.oid, n.nspname, c.relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.r
用户5005176
2021/03/19
8230
推荐阅读
相关推荐
PostgreSQL集群篇——常用的运维SQL
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档