2010-12-11 15 views
16

Je cherche une requête qui renvoie un résultat du formulaire pour n'importe quelle base de données (voir l'exemple ci-dessous en supposant que l'espace total utilisé par la base de données est 40GB)liste de schéma avec les tailles (relative et absolue) dans une base de données PostgreSQL

schema | size | relative size 
----------+------------------- 
foo | 15GB | 37.5%  
bar | 20GB |  50% 
baz | 5GB | 12.5% 

J'ai réussi à concocter une liste d'entités en utilisant l'espace dans la base de données triées par schéma, qui a été utile, mais obtenir un résumé par le schéma de cela ne semble pas si facile. Voir ci-dessous.

SELECT relkind, 
     relname, 
     pg_catalog.pg_namespace.nspname, 
     pg_size_pretty(pg_relation_size(pg_catalog.pg_class.oid)) 
FROM pg_catalog.pg_class 
     INNER JOIN pg_catalog.pg_namespace 
     ON relnamespace = pg_catalog.pg_namespace.oid 
ORDER BY pg_catalog.pg_namespace.nspname, 
      pg_relation_size(pg_catalog.pg_class.oid) DESC; 

Cela donne des résultats comme

relkind |    relname    |  nspname  | pg_size_pretty 
---------+---------------------------------------+--------------------+---------------- 
    r  | geno         | btsnp    | 11 GB 
    i  | geno_pkey        | btsnp    | 5838 MB 
    r  | anno         | btsnp    | 63 MB 
    i  | anno_fid_key       | btsnp    | 28 MB 
    i  | ix_btsnp_anno_rsid     | btsnp    | 28 MB 
    [...] 
    r  | anno         | btsnp_shard  | 63 MB 
    r  | geno4681        | btsnp_shard  | 38 MB 
    r  | geno4595        | btsnp_shard  | 38 MB 
    r  | geno4771        | btsnp_shard  | 38 MB 
    r  | geno4775        | btsnp_shard  | 38 MB 

Il ressemble à l'aide d'un opérateur d'agrégation comme SUM peut être nécessaire, sans succès avec ce jusqu'ici.

                    Regards, Faheem 
+0

Désolé, mods peut » t associez votre compte à d'autres comptes de site SE. Si vous vous inscrivez avec les mêmes informations sur le site tex, il devrait être associé automatiquement. Sinon, ouvrez une question sur meta et demandez de l'aide là-bas. – Will

+0

@Will: Les informations sur tous ces sites devraient être les mêmes. Ok, je vais le prendre à méta. Merci. –

Répondre

28

Essayez ceci:

SELECT schema_name, 
     sum(table_size), 
     (sum(table_size)/database_size) * 100 
FROM (
    SELECT pg_catalog.pg_namespace.nspname as schema_name, 
     pg_relation_size(pg_catalog.pg_class.oid) as table_size, 
     sum(pg_relation_size(pg_catalog.pg_class.oid)) over() as database_size 
    FROM pg_catalog.pg_class 
    JOIN pg_catalog.pg_namespace ON relnamespace = pg_catalog.pg_namespace.oid 
) t 
GROUP BY schema_name, database_size


Edit: juste remarqué la solution avec résumant toutes les tables pour obtenir la taille de la base de données n'est pas nécessaire:

 
SELECT schema_name, 
     pg_size_pretty(sum(table_size)::bigint), 
     (sum(table_size)/pg_database_size(current_database())) * 100 
FROM (
    SELECT pg_catalog.pg_namespace.nspname as schema_name, 
     pg_relation_size(pg_catalog.pg_class.oid) as table_size 
    FROM pg_catalog.pg_class 
    JOIN pg_catalog.pg_namespace ON relnamespace = pg_catalog.pg_namespace.oid 
) t 
GROUP BY schema_name 
ORDER BY schema_name 
+0

Merci beaucoup. Le JOIN ci-dessus est équivalent à INNER JOIN, oui? –

+0

Hmm. Je me demande s'il est possible de tronquer les valeurs de pourcentage à deux décimales, disons. –

+0

On peut faire - trunc ((somme (taille_table)/pg_database_size (current_database())) * 100, 2) AS pour cent. Merci à merlin83 sur #postgresql. –