Comment trouver la taille du disque d'une table Postgres / PostgreSQL et ses index

156

J'arrive à Postgres depuis Oracle et je cherche un moyen de trouver la table et la taille de l'index en termes de bytes/MB/GB/etc, voire mieux, la taille de toutes les tables. Dans Oracle, j'avais une longue requête désagréable qui regardait user_lobs et user_segments pour donner une réponse.

Je suppose que dans Postgres, je peux utiliser quelque chose dans les information_schematableaux, mais je ne vois pas où.

mmrobins
la source

Réponses:

271

Essayez les fonctions de taille d'objet de base de données . Un exemple:

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

Pour toutes les tables, quelque chose du genre:

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;

Edit: Voici la requête soumise par @phord, pour plus de commodité:

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;

Je l'ai légèrement modifié pour l'utiliser pg_table_size()pour inclure des métadonnées et faire en sorte que les tailles s'additionnent.

aib
la source
3
Soit dit en passant, si quelqu'un a des informations sur la façon d'aliaser la grande expression répétée, je serais heureux de l'entendre.
aib
2
Vous ne pouvez pas l'aliaser, mais vous pouvez toujours l'exécuter dans une sous-requête ... comme: SELECT table_full_name, pg_size_pretty (size) FROM (SELECT .. AS table_full_name, .. AS size FROM ....) x ORDER BY size
Magnus Hagander
1
Une suggestion: changer '"' || table_schema || '"."' || table_name || '"'en format('%I.%I', table_schema, table_name).
jpmc26
174

Afficher les tailles de base de données:

\l+

par exemple

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

Afficher les tailles de table:

\d+

par exemple

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

Ne fonctionne que dans psql.

(Résumé de la réponse de @ zkutch .)

Hendy Irawan
la source
28
Si vous avez besoin de voir à la fois les tables et les index, \dti+cela fera l'affaire.
tomasz
Cela renvoie cependant trié par nom, la première réponse est triée par taille décroissante
Izkata
23

Si le nom de la base de données est snort, la phrase suivante lui donne sa taille:

psql -c "\l+ snort" | awk -F "|" '{print $7}'
zkutch
la source
2
De loin la réponse la plus simple pour une vue rapide de la taille. J'ai mis cela dans une fonction shell dbsize.
RichVel
12

Tyr this: (Taille de l'index / statistiques d'utilisation)

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
la source
10

Les tables PostgreSQL ont trois composants: la table elle-même, tous les index qu'elle contient et potentiellement les données TOAST. Il existe quelques exemples montrant comment faire glisser et découper les informations disponibles de différentes manières sur http://wiki.postgresql.org/wiki/Disk_Usage

Greg Smith
la source
5

Juste pour info, j'ai eu l'excellente réponse de @aib et je l'ai un peu modifiée pour:

  • obtenir uniquement les tables du schéma "public"
  • afficher également les données des vues matérialisées et la taille de l'index

Sur la vue matérialisée, nous pouvons utiliser l'index pour actualiser les vues matérialisées simultanément , ce qui permet de les utiliser lors de la mise à jour.

Eh bien, ma requête sera la suivante:

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
la source
1

La requête ci-dessous vous servira

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;

Voir ce lien: https://wiki.postgresql.org/wiki/Disk_Usage

Sajeev
la source
0

vérifiez ce wiki. https://wiki.postgresql.org/wiki/Disk_Usage

SELECT *, pg_size_pretty (total_bytes) AS total
    , pg_size_pretty (index_bytes) COMME INDEX
    , pg_size_pretty (toast_bytes) AS toast
    , pg_size_pretty (table_bytes) AS TABLE
  DE (
  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
          DE pg_class c
          JOINT GAUCHE pg_namespace n ON n.oid = c.relnamespace
          O relkind = 'r'
  ) une
) une
Uma
la source
-1

Essayez ce script pour trouver toutes les tailles de table:

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

Pour d'autres scripts différents pour trouver la taille dans PostgreSQL, veuillez visiter cette url: http://www.dbrnd.com/2015/05/how-to-find-size-of-database-and-table-in-postgresql/

Anvesh
la source