¿Cómo encuentra el tamaño de disco de una tabla Postgres / PostgreSQL y sus índices?

156

Estoy llegando a Postgres desde Oracle y estoy buscando una manera de encontrar la tabla y el tamaño del índice en términos de bytes/MB/GB/etc, o incluso mejor, el tamaño de todas las tablas. En Oracle tuve una consulta larga y desagradable que analizaba user_lobs y user_segments para devolver una respuesta.

Supongo que en Postgres hay algo que puedo usar en las information_schematablas, pero no veo dónde.

mmrobins
fuente

Respuestas:

271

Pruebe las funciones de tamaño de objeto de base de datos . Un ejemplo:

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

Para todas las tablas, algo en la línea de:

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;

Editar: Aquí está la consulta enviada por @phord, por conveniencia:

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;

Lo modifiqué un poco para usarlo pg_table_size()para incluir metadatos y hacer que los tamaños se sumen.

aib
fuente
3
Por cierto, si alguien tiene información sobre cómo alias la expresión grande y repetida, me alegraría escucharla.
aib
2
No puede alias, pero siempre puede ejecutarlo en una subconsulta ... como: SELECT table_full_name, pg_size_pretty (size) FROM (SELECT .. AS table_full_name, .. AS size FROM ....) x ORDER BY size
Magnus Hagander
1
Una sugerencia: cambiar '"' || table_schema || '"."' || table_name || '"'a format('%I.%I', table_schema, table_name).
jpmc26
174

Mostrar tamaños de base de datos:

\l+

p.ej

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

Mostrar tamaños de mesa:

\d+

p.ej

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

Solo funciona en psql.

(Resumen de la respuesta de @ zkutch ).

Hendy Irawan
fuente
28
Si uno necesita ver tanto tablas como índices, \dti+hará el truco.
tomasz
Sin embargo, esto regresa ordenado por nombre, la respuesta principal regresa ordenada por tamaño descendente
Izkata
23

Si el nombre de la base de datos es snort, la siguiente oración le da tamaño:

psql -c "\l+ snort" | awk -F "|" '{print $7}'
zkutch
fuente
2
Con mucho, la respuesta más simple para una vista rápida del tamaño. He puesto esto en una función de shell dbsize.
RichVel
12

Tyr esto: (Tamaño del índice / estadísticas de uso)

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;
Ahmed MANSOUR
fuente
10

Las tablas PostgreSQL tienen tres componentes: la tabla en sí, cualquier índice que contenga y, posiblemente, los datos de TOAST. Hay un par de ejemplos que muestran cómo deslizar y cortar la información disponible de varias maneras en http://wiki.postgresql.org/wiki/Disk_Usage

Greg Smith
fuente
5

Solo para información, recibí la excelente respuesta de @aib y la modifiqué un poco para:

  • obteniendo solo tablas del esquema "público"
  • mostrar también datos de vistas materializadas y tamaño de índice

En la vista materializada, podemos usar el índice para actualizar las vistas materializadas simultáneamente , lo que permite usarlas durante la actualización.

Bueno, mi consulta será la siguiente:

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
Ciges
fuente
1

La consulta a continuación le servirá

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;

Ver este enlace: https://wiki.postgresql.org/wiki/Disk_Usage

Sajeev
fuente
0

mira esta wiki https://wiki.postgresql.org/wiki/Disk_Usage

SELECT *, pg_size_pretty (total_bytes) AS total
    , pg_size_pretty (index_bytes) COMO ÍNDICE
    , pg_size_pretty (toast_bytes) AS brindis
    , pg_size_pretty (table_bytes) COMO TABLA
  DE (
  SELECT *, total_bytes-index_bytes-COALESCE (toast_bytes, 0) AS table_bytes FROM (
      SELECCIONE 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
          DE pg_class c
          IZQUIERDA UNIRSE pg_namespace n ON n.oid = c.relnamespace
          DONDE relkind = 'r'
  ) una
) una
Uma
fuente
-1

Pruebe este script para encontrar todos los tamaños de tabla:

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

Para ver otro script diferente para encontrar el tamaño en PostgreSQL, visite esta url: http://www.dbrnd.com/2015/05/how-to-find-size-of-database-and-table-in-postgresql/

Anvesh
fuente