首页 > 数据库 >用于PostgreSQL索引维护的有用查询

用于PostgreSQL索引维护的有用查询

时间:2024-01-13 21:00:28浏览次数:49  
标签:index PostgreSQL 查询 索引 accounts pg pgbench size

PostgreSQL 拥有丰富的索引功能,并且有很多文章解释索引的语法、用法和价值。在本文中,我将编写基本且有用的查询来查看数据库索引的状态。人们开发数据库一段时间后,当需要对软件架构进行更改时,他们忘记了以前的索引清理。这种方法会造成混乱,有时还会因为索引太多而降低数据库速度。每当我们进行更新或插入时,索引都会与实际表一起更新,因此需要进行清理。

有一个 wiki 页面有一些与PostgreSQL 索引维护相关的查询。

在编写查询之前,我想介绍一个目录表 pg_index。该表包含有关索引的信息。这是基本的目录表,所有基于索引的视图都使用同一个表。

  1. 有时您需要查看表有多少个索引。此查询将显示模式限定的表名称及其索引名称。

    SELECT CONCAT(n.nspname,'.', c.relname) AS table,
        i.relname AS index_name FROM pg_class c
         JOIN pg_index x ON c.oid = x.indrelid
         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 like 'pgbench_accounts';
              table          | index_name       
    -------------------------+------------------------
     public.pgbench_accounts | pgbench_accounts_pkey
     public.pgbench_accounts | pgbench_accounts_index
    (2 rows)
    
  2. 众所周知,索引是一种性能特征,但除此之外,它还用于确保唯一性。但为了确保唯一性,我们需要一种单独类型的索引,称为唯一索引。为了检查索引是否唯一,pg_index 有一个名为“indisunique”的列来标识索引的唯一性。

    SELECT    i.relname AS index_name,
              indisunique is_unique
    FROM      pg_class c
    JOIN      pg_index x ON c.oid = x.indrelid
    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 LIKE 'pgbench_accounts';
           index_name       | is_unique 
    ------------------------+-----------
     pgbench_accounts_pkey  | t
     pgbench_accounts_index | f
    (2 rows)
    
  3. 有一个非常简单的方法来获取 PostgreSQL 索引的大小。这是一个列出 PostgreSQL 大小的查询。

    SELECT pg_size_pretty(pg_relation_size('pgbench_accounts_index'));
     pg_size_pretty 
    ----------------
     132 MB
    (1 row)
    
  4. 这是索引列表,其中包含表总大小和索引大小,这对于将表大小与其相应索引进行比较非常有用。了解表的大小、索引以及表的总大小非常有用。

    SELECT    CONCAT(n.nspname,'.', c.relname) AS table,
              i.relname AS index_name, pg_size_pretty(pg_relation_size(x.indrelid)) AS table_size,
              pg_size_pretty(pg_relation_size(x.indexrelid)) AS index_size,
              pg_size_pretty(pg_total_relation_size(x.indrelid)) AS total_size FROM pg_class c 
    JOIN      pg_index x ON c.oid = x.indrelid
    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       n.oid NOT IN (99, 11, 12375);
              table          | index_name       | table_size | index_size | total_size 
    -------------------------+------------------------+------------+------------+------------
     public.pgbench_tellers  | pgbench_tellers_pkey   | 88 kB      | 64 kB  | 152 kB
     public.pgbench_accounts | pgbench_accounts_pkey  | 2561 MB    | 428 MB | 3122 MB
     public.pgbench_accounts | pgbench_accounts_index | 2561 MB    | 132 MB | 3122 MB
     public.pgbench_branches | pgbench_branches_pkey  | 8192 bytes | 16 kB  | 24 kB
    (4 rows)
    

    pg_relation_size:函数给出关系的大小。它用于获取表/索引的大小。

    pg_total_relation_size:这是一个特殊函数,给出表及其所有索引的总大小。

  5. 获取索引的查询。该查询将显示索引创建查询。

    SELECT pg_get_indexdef(indexrelid) AS index_query
    FROM   pg_index WHERE  indrelid = 'pgbench_accounts'::regclass;
                                         index_query
    ----------------------------------------------------------------------------------------
    CREATE UNIQUE INDEX pgbench_accounts_pkey ON public.pgbench_accounts USING btree (aid)
    CREATE INDEX pgbench_accounts_index ON public.pgbench_accounts USING btree (bid)
    CREATE INDEX pgbench_accounts_index_dup ON public.pgbench_accounts USING btree (bid)
    (3 rows)
    
  6. 如果您的索引损坏或膨胀,您需要重新构建该索引。同时,您不想阻止表上的操作,因此您可以选择 REINDEX CONCURRENTLY 命令。

    REINDEX INDEX CONCURRENTLY idx;
    REINDEX
    
  7. PostgreSQL 有许多索引方法,如 BTree、Hash、BRIN、GIST 和 GIN。有时我们想在列上创建一些特定的索引但无法做到这一点。PostgreSQL 存在一些限制,即某些索引无法在某些数据类型和运算符上创建,这也是有道理的。例如,哈希索引只能用于等于运算符。以下查询用于获取特定索引支持的数据类型列表。

    SELECT amname,
           opfname
    FROM   pg_opfamily,
           pg_am
    WHERE  opfmethod = pg_am.oid
    AND    amname = 'btree';
    
    amname | opfname
    --------+--------------------
    btree  | array_ops
    btree  | bit_ops
    btree  | bool_ops
    …
    
  8. 此查询将找到未使用的索引。如果index_scans 为0 或接近0,那么您可以删除这些索引。但要小心,因为这些索引可能有独特的用途。

    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;
    table_name       | index_name            | indisunique | index_scans
    ------------------+-----------------------+-------------+-------------
    pgbench_branches | pgbench_branches_pkey | t           | 0
    pgbench_tellers  | pgbench_tellers_pkey  | t           | 0
    pgbench_accounts | pgbench_accounts_pkey | t           | 0
    (3 rows)
    
  9. 用于查找重复索引的查询。在此示例中,pgbench_accounts 有两个相同的索引。一个表上不需要有多个具有不同名称的相同索引。正如我们已经讨论过的,在更新/插入的情况下,所有索引都会与实际表一起更新,这会损害性能。

    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;
    table_name | column_name | index_method
    ------------+-------------+--------------
    foo        | a           | btree
    
    (1 row)
    

总结

PostgreSQL 有系统表来存储索引信息,因此,我们可以根据需要编写任意数量的查询。本博客展示了一些基本查询,并展示了如何使用系统表来编写查询。

标签:index,PostgreSQL,查询,索引,accounts,pg,pgbench,size
From: https://www.cnblogs.com/jl1771/p/17962923

相关文章

  • 索引的一些总结
    索引的一些总结 1.1.1摘要如果说要对数据库进行优化,我们主要可以通过以下五种方法,对数据库系统进行优化。1.计算机硬件调优2.应用程序调优3.数据库索引优化4.SQL语句优化5.事务处理调优在本篇博文中,我们将想大家讲述数据库中索引类型和使用场合,本文以SQLServer......
  • POSTGRESQL中ETL、fdw的平行替换
    01、简介“在我前两次的文章中,说到postgresql对于python的支持,其实很多功能也就可以封装进入的postgresql数据库中去。比如fdw、etl等,本文将以此为叙述点,进行演示展示”在postgresql数据库中fdw的支持,在创建和使用上都不上太方便,特别是fdw在用表级别关联的时候,性能会大大折扣,因为f......
  • 【ubantu22.10】安装部署timescaledbv2.13.0及postgresql v14.10
    一、安装部署postgresql-timescaledbaptinstallgnupgpostgresql-commonapt-transport-httpslsb-releasewget二、运行postgresql存储库设置脚本/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh三、添加timescaledb第三方存储库echo"debhttps://packageclo......
  • 若依前后端分离版关联字典值查询数据工具类使用
    场景若依管理系统导出Excel时添加没有的列和关联码表显示中文进行导出:若依管理系统导出Excel时添加没有的列和关联码表显示中文进行导出_若依的导出添加额外的字段信息上面通过关联表的方式实现查询字典值,若依本身提供了查询redis中缓存的字典值的相关方法。可不修改sql的方式去调......
  • thinkphp6的join连表查询
    说明join要关联的(完整)表名以及别名,支持三种写法:写法1:['完整表名或者子查询'=>'别名']写法2:'完整表名别名'写法3:'不带数据表前缀的表名'condition关联条件,可以为字符串或数组,为数组时每一个元素都是一个关联条件。type关联类型,可以为:INNER、LEFT、RIGHT、FULL,......
  • ES--RestClient查询文档
    文档的查询同样适用昨天学习的RestHighLevelClient对象,基本步骤包括:1)准备Request对象2)准备请求参数3)发起请求4)解析响应1.快速入门我们以match_all查询为例1.发起查询请求 代码解读:第一步,创建SearchRequest对象,指定索引库名第二步,利用request.source()......
  • openGauss学习笔记-195 openGauss 数据库运维-常见故障定位案例-分析查询语句运行状态
    openGauss学习笔记-195openGauss数据库运维-常见故障定位案例-分析查询语句运行状态195.1分析查询语句运行状态195.1.1问题现象系统中部分查询语句运行时间过长,需要分析查询语句的运行状态。195.1.2处理办法以操作系统用户omm登录主机。使用如下命令连接数据库。gs......
  • openGauss学习笔记-194 openGauss 数据库运维-常见故障定位案例-分析查询语句长时间运
    openGauss学习笔记-194openGauss数据库运维-常见故障定位案例-分析查询语句长时间运行的问题194.1分析查询语句长时间运行的问题194.1.1问题现象系统中部分查询语句运行时间过长。194.1.2原因分析查询语句较为复杂,需要长时间运行。查询语句阻塞。194.1.3处理办法......
  • ES--地理坐标查询
    所谓的地理坐标查询,其实就是根据经纬度查询,官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-queries.html常见的使用场景包括:携程:搜索我附近的酒店滴滴:搜索我附近的出租车微信:搜索我附近的人 矩形范围查询,也就是geo_bounding_box查询......
  • ES--全文检索查询
    全文检索查询的基本流程如下:对用户搜索的内容做分词,得到词条根据词条去倒排索引库中匹配,得到文档id根据文档id找到文档,返回给用户比较常用的场景包括:商城的输入框搜索百度输入框搜索常见的全文检索查询包括:match查询:单字段查询multi_match查询:多字段查......