【问题标题】:How do you find the disk size of a Postgres / PostgreSQL table and its indexes您如何找到 Postgres / PostgreSQL 表及其索引的磁盘大小
【发布时间】:2011-02-05 11:59:50
【问题描述】:

我从 Oracle 来到 Postgres,并寻找一种方法来查找表和索引大小,以 bytes/MB/GB/etc 为单位,甚至更好地查找所有表的大小。在 Oracle 中,我有一个令人讨厌的长查询,它查看了 user_lobs 和 user_segments 以给出答案。

我假设在 Postgres 中有一些我可以在 information_schema 表中使用的东西,但我不知道在哪里。

【问题讨论】:

标签: postgresql


【解决方案1】:

试试这个:(索引大小/使用统计)

SELECT
    t.tablename,
    indexname,
    c.reltuples AS num_rows,
    pg_size_pretty(pg_relation_size(quote_ident(t.tablename)::text)) AS table_size,
    pg_size_pretty(pg_relation_size(quote_ident(indexrelname)::text)) AS index_size,
    CASE WHEN indisunique THEN 'Y'
       ELSE 'N'
    END AS UNIQUE,
    idx_scan AS number_of_scans,
    idx_tup_read AS tuples_read,
    idx_tup_fetch AS tuples_fetched
FROM pg_tables t
LEFT OUTER JOIN pg_class c ON t.tablename=c.relname
LEFT OUTER JOIN
    ( SELECT c.relname AS ctablename, ipg.relname AS indexname, x.indnatts AS number_of_columns, idx_scan, idx_tup_read, idx_tup_fetch, indexrelname, indisunique FROM pg_index x
           JOIN pg_class c ON c.oid = x.indrelid
           JOIN pg_class ipg ON ipg.oid = x.indexrelid
           JOIN pg_stat_all_indexes psai ON x.indexrelid = psai.indexrelid )
    AS foo
    ON t.tablename = foo.ctablename
WHERE t.schemaname='public'
ORDER BY 1,2;

【讨论】:

    【解决方案2】:

    如果数据库名称是snort,下面这句话给它大小:

    psql -c "\l+ snort" | awk -F "|" '{print $7}'
    

    【讨论】:

    • 迄今为止快速查看尺寸的最简单答案。我已经把它放在一个shell函数dbsize
    • 另外,您可以将-t 添加到psql 命令以避免输出中出现列标题(这对自动化很有用),例如:psql -c "\l+ snort" -t | awk -F "|" '{print $7}'
    【解决方案3】:

    试试Database Object Size Functions。一个例子:

    SELECT pg_size_pretty(pg_total_relation_size('"<schema>"."<table>"'));
    

    对于所有表格,大致如下:

    SELECT
        table_schema || '.' || table_name AS table_full_name,
        pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) AS size
    FROM information_schema.tables
    ORDER BY
        pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC;
    

    编辑:为方便起见,这是@phord 提交的查询:

    SELECT
        table_name,
        pg_size_pretty(table_size) AS table_size,
        pg_size_pretty(indexes_size) AS indexes_size,
        pg_size_pretty(total_size) AS total_size
    FROM (
        SELECT
            table_name,
            pg_table_size(table_name) AS table_size,
            pg_indexes_size(table_name) AS indexes_size,
            pg_total_relation_size(table_name) AS total_size
        FROM (
            SELECT ('"' || table_schema || '"."' || table_name || '"') AS table_name
            FROM information_schema.tables
        ) AS all_tables
        ORDER BY total_size DESC
    ) AS pretty_sizes;
    

    我对其稍作修改以使用 pg_table_size() 以包含元数据并使大小相加。

    【讨论】:

    • 顺便说一句,如果有人知道如何为大而重复的表达式取别名,我会很高兴听到。
    • 你不能给它取别名,但你总是可以在子查询中运行它......比如: SELECT table_full_name,pg_size_pretty(size) FROM ( SELECT .. AS table_full_name, .. AS size FROM 。 ... ) x 按尺寸排序
    • 一个建议:把'"' || table_schema || '"."' || table_name || '"'改成format('%I.%I', table_schema, table_name)
    • 跳过pg_size_pretty,如果您希望以编程方式处理原始字节数,例如用于您自己的javascript仪表板,只需执行内部查询。
    【解决方案4】:

    仅供参考,我从@aib 得到了很好的答案,并对其进行了一些修改:

    • 仅从“公共”架构中获取表
    • 还显示物化视图数据和索引大小

    在物化视图上,我们可以使用refreshing materialized views concurrently 的索引,这允许在更新时使用它们。

    好吧,我的查询将如下:

    SELECT
        table_name,
        pg_size_pretty(table_size) AS table_size,
        pg_size_pretty(indexes_size) AS indexes_size,
        pg_size_pretty(total_size) AS total_size
    FROM (
        SELECT
            table_name,
            pg_table_size(table_name) AS table_size,
            pg_indexes_size(table_name) AS indexes_size,
            pg_total_relation_size(table_name) AS total_size
        FROM (
            -- tables from 'public'
            SELECT table_name
            FROM information_schema.tables
            where table_schema = 'public' and table_type = 'BASE TABLE'
            union
            -- materialized views
            SELECT oid::regclass::text as table_name
            FROM pg_class
            WHERE relkind = 'm'
            order by table_name
        ) AS all_tables
        -- ORDER BY total_size DESC
        order by table_name
    ) AS pretty_sizes
    

    【讨论】:

    • 我认为在-- tables from 'public' 子查询中,table_name 需要转换为文本。进行更改后,该查询对我有用。没有它,我会在 pg_table_size 函数上得到一个泛型类型错误。 table_name 的类型为 information_schema.sql_identifier
    【解决方案5】:

    下面的查询将为您服务

    SELECT nspname || '.' || relname AS "relation",
      pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
    FROM pg_class C
    LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
    WHERE nspname NOT IN ('pg_catalog', 'information_schema')
      AND C.relkind <> 'i'
      AND nspname !~ '^pg_toast'
    ORDER BY pg_total_relation_size(C.oid) DESC
    LIMIT 20;
    

    查看此链接:https://wiki.postgresql.org/wiki/Disk_Usage

    【讨论】:

      【解决方案6】:

      检查这个维基。 https://wiki.postgresql.org/wiki/Disk_Usage

      SELECT *, pg_size_pretty(total_bytes) 作为总计 , pg_size_pretty(index_bytes) 作为索引 , pg_size_pretty(toast_bytes) 作为吐司 , pg_size_pretty(table_bytes) 作为表 从 ( SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes FROM ( SELECT c.oid,nspname AS table_schema, relname AS TABLE_NAME , c.reltuples AS row_estimate , pg_total_relation_size(c.oid) AS total_bytes , pg_indexes_size(c.oid) AS index_bytes , pg_total_relation_size(reltoastrelid) AS toast_bytes FROM pg_class c 左连接 pg_namespace n ON n.oid = c.relnamespace WHERE relkind = 'r' ) 一种 ) 一种

      【讨论】:

        【解决方案7】:

        试试这个脚本来查找所有表格大小:

        SELECT
            table_schema || '.' || table_name AS TableName,
            pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) AS TableSize
        FROM information_schema.tables
        ORDER BY
            pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC
        

        有关在 PostgreSQL 中查找大小的其他不同脚本,请访问以下网址: http://www.dbrnd.com/2015/05/how-to-find-size-of-database-and-table-in-postgresql/

        【讨论】:

          【解决方案8】:

          显示数据库大小:

          \l+

          例如

          => \l+
           berbatik_prd_commerce    | berbatik_prd     | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                       | 19 MB   | pg_default | 
           berbatik_stg_commerce    | berbatik_stg     | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                       | 8633 kB | pg_default | 
           bursasajadah_prd         | bursasajadah_prd | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                       | 1122 MB | pg_default | 
          

          显示表格大小:

          \d+

          例如

          => \d+
           public | tuneeca_prd | table | tomcat | 8192 bytes | 
           public | tuneeca_stg | table | tomcat | 1464 kB    | 
          

          仅适用于psql

          @zkutch's answer的总结。)

          【讨论】:

          • 如果需要同时查看表和索引,\dti+ 可以解决问题。
          • 虽然返回按名称排序,但最重要的答案返回按大小降序排序
          【解决方案9】:

          PostgreSQL 表具有三个组成部分:表本身、其上的任何索引以及可能的 TOAST 数据。 http://wiki.postgresql.org/wiki/Disk_Usage

          【讨论】:

            猜你喜欢
            • 2013-04-06
            • 1970-01-01
            • 2018-02-08
            • 2018-01-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-03-22
            • 1970-01-01
            相关资源
            最近更新 更多