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

news2024/11/16 17:26:57

2fb246216d27e05e33c861c825294b00.png

随着问问题的同学越来越多,公众号内部私信回答问题已经很困难了,所以建立了一个群,关于各种数据库的问题都可以,目前主要是 POSTGRESQL, MYSQL ,MONGODB ,POLARDB ,REDIS,SQL SERVER 等,期待你的加入,加群请添加微信liuaustin3.  (群里有各方面的工作人员和专家)

好长时间不进行研究了,最近被突发的问题想到了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 的情况

3d2438d88e1abe20aff94bac76b9b800.png

64ceabb4460632257acabc37b20639be.png

所以结论是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;

8411c777e36f0c05a782194b9dc50586.png

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

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

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';

9db0bfc495c59e7a4478334628ee36ac.png

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

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;

845130f685ae978de828a8bb7a41f7d0.png

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

FROM pg_index 

GROUP BY    indrelid    ,indkey 

HAVING COUNT(*) > 1;

ca28d5f6ed8e6b35f547d64f963ee677.png

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

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

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=# 

d7da39aafc7c42cd7c47921cb2f01b1e.png

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;

1f51b9f16718678374ab10f1c4682a13.png

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;

3f1df9cb14d08d1bfe0a03f54c4df4eb.png

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

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

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

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

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

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

d6e996344d5caf6d790a264475855b37.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/107925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[洛谷]P1996 约瑟夫问题

[洛谷]P1996 约瑟夫问题一、问题描述题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示二、思路分析1、算法标签&#xff1a;2、算法分析&#xff1a;三、代码实现1、环形链表2、队列一、问题描述 [洛谷]P1996 约瑟夫问题 题目描述 nnn 个人围成一圈&#xff0c;从…

3.Spark 操作

基于centos7 ,hadoop2.7.3, spark-2.4.4-bin-hadoop2.7.tgz 目录: 一.spark shell二. 读取hdfs文件三.Idea中编写wordcount一.spark shell 在spark shell中编写wordcount程序读取本地文件 1、准备数据源(创建目录,创建文件) 2.代码: --注意修改文件地址-- sc.textF…

【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.8 画刷设置

本节对应的视频讲解&#xff1a;B_站_视_频 https://www.bilibili.com/video/BV1A44y1Z7vz 本节讲解画刷的设置&#xff0c;包括画刷的颜色和样式 画刷设置完后&#xff0c;就可以把该画刷设置给 QPainter 了 1. 相关 API 1.1 画刷颜色 // 获取和设置画刷的颜色 const QCo…

新冠阳性的第三篇博客,使用Swagger管理API

新冠阳性的第三篇博客&#xff0c;使用Swagger管理API1.Swagger简介2.在项目中使用Swagger3.配置swagger4.swagger配置扫描接口5.配置API文档的分组6.swagger的实体类扫描7.给Controller加文档注释今天是新冠确诊的第二天&#xff0c;得了新冠也不要忘记学习啊&#xff01;&…

一文读懂自动驾驶汽车:软硬结合 造就未来出行体验(上篇)

在 GTC 2022 秋季大会上&#xff0c;NVIDIA 汽车部门营销经理 Katie Burke Washabaugh&#xff0c;面向想要了解自动驾驶汽车、并有志于投身自动驾驶行业的观众&#xff0c;介绍了自动驾驶汽车的历史、工作原理、相关技术以及发展前景。本文对此次分享的精华内容进行了汇总和整…

基于蒙特卡诺的电动汽车对电网影响(数据+Matlab代码)

目录 0 知识回顾 1 电网没考虑电动汽车时 1.1 案例1&#xff08;4kw&#xff09; 1.2 案例2&#xff08;7kw&#xff09; 31.3 案例3&#xff08;20kw&#xff09; 2 静态测试 2.1 收敛的最优结果 2.2 改变电动汽车数量的影响 2.3 收敛的最优结果 3 动态测试 4 一…

图结构

图结构 从哥尼斯堡的七桥问题开始 ▪ 18世纪初普鲁士的哥斯尼堡,有一条河穿过,河上有两个小岛,有七座桥把两个小岛与河岸联系起来 ▪ 问题:一个步行者怎样才能不重复、不遗漏地一次走完七座桥&#xff0c;最后回到出发点。 ▪ 难点&#xff1a;可能的走法----7&#xff01;5…

苹果给出 AirTag 固件更新日志,苹果Find My功能越来越完善

自 11 月以来&#xff0c;苹果已经为其 AirTag 物品追踪器发布了两个固件更新。然而&#xff0c;该公司此前并没有详细说明这些更新带来了什么变化。不过有网友发现&#xff0c;苹果终于分享了最新 AirTag 固件更新的更新内容。 以下是 AirTag 固件更新 2.0.24 和 2.0.36 带来…

[力扣c++实现]85. 最大矩形

85. 最大矩形 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”…

2022最新最全的Java面试八股文小抄开源!带你摸熟 20+ 互联网公司面试考点

2022真是多变的一年&#xff0c;相对往年我们会发现今年猎头电话少了&#xff0c;大部分企业年终奖缩水&#xff0c;加薪幅度也不如往年&#xff0c;选择好 offer 就要趁早&#xff0c;现在开始准备吧&#xff0c;刷一波 Java 面试题&#xff0c;能回答 70%就去 BATJTMD 大胆试…

基于SSM实现的网上手机商城项目(附源码)

基于SpringSpring MVCMyBatisLayui框架 项目完整源码下载 https://download.csdn.net/download/DeepLearning_/87327169 功能&#xff1a; 前台 登录、注册、注销查看商品、商品评论、热销商品收藏、取消收藏商品加入购物车购物车增、删、改、查购买商品、确认收货、删除已…

stop pin/ignore pin/exclude pin/float pin

stop pin、ignore pin、exclude pin和float pin的区别如下图&#xff1a; 1、Stop pins stop pin是clock tree的leaf pin&#xff0c;作为clock tree的终点&#xff0c;需要balance insertion delay&#xff08;latency&#xff09;&#xff0c;clock sink都是stop pin。 2、…

七、http模块

HTTP —— 超文本传输协议&#xff0c;用于规范客户端浏览器和服务端以何种格式进行通信和数据交互&#xff1b;HTTP由请求和响应构成的&#xff0c;是一个标准的客服端服务器模型。 HTTP请求响应过程 先简单的来了解以下HTTP的请求响应过程&#xff1a;1.地址解析&#xff1a…

普通人为什么要学习python?有什么用

为什么要学习python&#xff1f; 比如新媒体职业&#xff1a; 1、简单来说&#xff0c;你会python后就相当于自己建造一个属于自己工作区块的微博热搜榜。你可以利用爬虫、收据抓取等技术知道哪些话题近期特别火&#xff0c;为什么火、有什么共通点&#xff0c;然后根据这些依…

3.1 多集放大电路的耦合方式

在实际应用中&#xff0c;常对放大电路的性能提出多方面的要求。所以&#xff0c;仅靠任何一种基本的放大电路并不能满足要求&#xff0c;此时可以选择多个基本放大电路级联在一起构成多级放大电路。 组成多级放大电路的每一个基本放大电路称为一级&#xff0c;级与级之间的连接…

Win11的两个实用技巧系列之玩游戏闪跳、错误代码0x80004005解决

Win11玩游戏经常无缘无故跳回桌面怎么解决? 最近有Win11用户反应&#xff0c;自己在玩游戏的时候遇到了经常无缘无故跳回桌面的情况&#xff0c;本文就为大家带来了详细的解决方法&#xff0c;需要的朋友一起看看吧 最近有Win11用户反应&#xff0c;自己在玩游戏的时候遇到了…

关于ShardingSphere内置分片算法及其数据倾斜问题总结

ShardingSphere是一款不错的分库分表中间件&#xff0c;并且其内置提供了多种分片算法。但是使用内置的分片算法会造成数据倾斜问题。下面以5.2.0版本的ShardingSphere详细介绍下几种内置分片算法并且分析下数据倾斜问题。 一、ShardingSphere内置分片算法介绍 根据官网描述&…

web前端-javascript-包装类(String,Number,Boolean,基本数据类型调用方法先转换为对象再调换)

包装类 1. 说明 在 JS 中为我们提供了三个包装类&#xff0c;通过这三个包装类可以将基本数据类型的数据转化为对象String() 可以将基本数据类型字符串转换为 String 对象 Number() 可以将基本数据类型的数字转换为 Number 对象 Boolean() 可以将基本数据类型的布尔值转换为 …

【C语言】重要函数atoi的使用

目录 一、atoi函数的介绍 二、atoi函数的使用 三、atoi函数的模拟实现 一、atoi函数的介绍 一个专门将字符串转换为整数的库函数&#xff0c;具体用法如下&#xff1a; 字符串str&#xff0c;将其内容转化为整数&#xff0c;该整数作为int值返回。 二、atoi函数的使用 atoi函…

CentOS7安装apache2并启动

CentOS7安装apache2并启动源码安装启动和停止源码安装 地址&#xff1a;https://downloads.apache.org/httpd/ https://downloads.apache.org/httpd/httpd-2.4.54.tar.gz 参考&#xff1a;https://www.cnblogs.com/xiangqs/p/8663947.html 启动和停止 网上搜到的都是/usr/lo…