Il existe trois façons d'obtenir ce type de décompte, chacune avec ses propres compromis.
Si vous voulez un vrai nombre, vous devez exécuter l'instruction SELECT comme celle que vous avez utilisée pour chaque table. Cela est dû au fait que PostgreSQL conserve les informations de visibilité des lignes dans la ligne elle-même, pas ailleurs, donc tout décompte précis ne peut être relatif qu'à une transaction. Vous obtenez un décompte de ce que cette transaction voit au moment où elle s'exécute. Vous pouvez automatiser cela pour qu'il s'exécute sur chaque table de la base de données, mais vous n'avez probablement pas besoin de ce niveau de précision ou vous voulez attendre aussi longtemps.
La deuxième approche note que le collecteur de statistiques suit à peu près combien de lignes sont "en direct" (non supprimées ou obsolètes par les mises à jour ultérieures) à tout moment. Cette valeur peut être légèrement inférieure en cas d'activité intense, mais est généralement une bonne estimation:
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
Cela peut également vous montrer combien de lignes sont mortes, ce qui est en soi un nombre intéressant à surveiller.
La troisième méthode consiste à noter que la commande système ANALYZE, qui est exécutée régulièrement par le processus de vide automatique à partir de PostgreSQL 8.3 pour mettre à jour les statistiques de table, calcule également une estimation de ligne. Vous pouvez saisir celui-ci comme ceci:
SELECT
nspname AS schemaname,relname,reltuples
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE
nspname NOT IN ('pg_catalog', 'information_schema') AND
relkind='r'
ORDER BY reltuples DESC;
Laquelle de ces requêtes est préférable d'utiliser est difficile à dire. Normalement, je prends cette décision selon qu'il y a des informations plus utiles que je veux également utiliser à l'intérieur de pg_class ou à l'intérieur de pg_stat_user_tables. À des fins de comptage de base, juste pour voir à quel point les choses sont grandes en général, l'une ou l'autre devrait être suffisamment précise.
with tbl as (SELECT table_schema,table_name FROM information_schema.tables where table_name not like 'pg_%' and table_schema in ('public')) select table_schema, table_name, (xpath('/row/c/text()', query_to_xml(format('select count(*) as c from %I.%I', table_schema, table_name), false, true, '')))[1]::text::int as rows_n from tbl ORDER BY 3 DESC;
n_live_tup
? Ma base de données Redshift n'a pas cette colonne. C'est un dérivé de Postgres 8.0.2.pg_stat_user_tables
) a renvoyé principalement des zérosn_live_tup
pour moi car elleANALYZE
n'avait jamais été exécutée. Plutôt que de courirANALYZE
sur chaque schéma / table et d'attendre indéfiniment une réponse, j'ai d'abord vérifié les résultats en utilisant la «troisième approche» et celle-ci (en utilisantpg_class
) a retourné des comptes très précis.Voici une solution qui ne nécessite pas de fonctions pour obtenir un décompte précis pour chaque table:
query_to_xml
exécutera la requête SQL passée et renverra un XML avec le résultat (le nombre de lignes pour cette table). L'extérieurxpath()
extraira ensuite les informations de comptage de ce xml et les convertira en un nombreLa table dérivée n'est pas vraiment nécessaire, mais la rend
xpath()
un peu plus facile à comprendre - sinon le toutquery_to_xml()
devrait être passé à laxpath()
fonction.la source
query_to_jsonb()
.select count(*)
sur chaque table.xpath()
fonction n'est appliquée qu'à une seule ligne - le résultat de lacount(*)
Pour obtenir des estimations, voir la réponse de Greg Smith .
Pour obtenir des chiffres exacts, les autres réponses à ce jour sont en proie à certains problèmes, certains graves (voir ci-dessous). Voici une version qui, espérons-le, est meilleure:
Il prend un nom de schéma comme paramètre, ou
public
si aucun paramètre n'est donné.Pour travailler avec une liste spécifique de schémas ou une liste provenant d'une requête sans modifier la fonction, elle peut être appelée à partir d'une requête comme celle-ci:
Cela produit une sortie à 3 colonnes avec le schéma, la table et le nombre de lignes.
Voici maintenant quelques problèmes dans les autres réponses que cette fonction évite:
Les noms de table et de schéma ne doivent pas être injectés dans SQL exécutable sans être cités, avec
quote_ident
ou avec laformat()
fonction plus moderne avec sa%I
chaîne de format. Sinon, une personne malveillante peut nommer sa table,tablename;DROP TABLE other_table
ce qui est parfaitement valide en tant que nom de table.Même sans les problèmes d'injection SQL et de caractères amusants, le nom de la table peut exister dans des variantes différentes selon la casse. Si une table est nommée
ABCD
et une autreabcd
, leSELECT count(*) FROM...
doit utiliser un nom entre guillemets sinon il sauteraABCD
et compteraabcd
deux fois. Le%I
format de fait cela automatiquement.information_schema.tables
répertorie les types composites personnalisés en plus des tables, même lorsque table_type vaut'BASE TABLE'
(!). En conséquence, nous ne pouvons pas répéterinformation_schema.tables
, sinon nous risquons d'avoirselect count(*) from name_of_composite_type
et cela échouerait. OTOHpg_class where relkind='r'
devrait toujours fonctionner correctement.Le type de COUNT () ne l'est
bigint
pasint
. Des tables avec plus de 2,15 milliards de lignes peuvent exister (cependant, exécuter un décompte (*) est une mauvaise idée).Il n'est pas nécessaire de créer un type permanent pour qu'une fonction renvoie un jeu de résultats avec plusieurs colonnes.
RETURNS TABLE(definition...)
est une meilleure alternative.la source
Si cela ne vous dérange pas les données potentiellement périmées, vous pouvez accéder aux mêmes statistiques utilisées par l'optimiseur de requêtes .
Quelque chose comme:
la source
ANALYZE
sur la table, les statistiques peuvent être très éloignées. Il s'agit de la charge de la base de données et de la configuration de la base de données (si les statistiques sont mises à jour plus fréquemment, les statistiques seront plus précises, mais cela pourrait réduire les performances d'exécution). En fin de compte, la seule façon d'obtenir des données précises est de s'exécuterselect count(*) from table
pour toutes les tables.La réponse hacky et pratique pour les gens qui essaient d'évaluer le plan Heroku dont ils ont besoin et ne peuvent pas attendre que le compteur de lignes lentes de Heroku se rafraîchisse:
Fondamentalement , vous voulez exécuter
\dt
danspsql
, copier les résultats dans votre éditeur de texte favori (il ressemblera à ceci:), puis lancez une recherche d'expression régulière et remplacez comme ceci:
à:
ce qui vous donnera quelque chose de très similaire à ceci:
(Vous devrez supprimer le dernier
union
et ajouter manuellement le point-virgule à la fin)Exécutez-le
psql
et vous avez terminé.la source
select '$1', count(*) from $1 union/g
/g
(conserverunion
) et ajouter un point-virgule (;
) à la toute fin. N'oubliez pas de supprimer le dernierunion
avant le point-virgule.union
avant le point-virgule", c'est ce que je voulais dire :) Ajout du mot "dernier" pour clarifierJe ne sais pas si une réponse en bash vous convient, mais FWIW ...
la source
select count(*) from table_name;
dans l'OP!Je ne me fie généralement pas aux statistiques, en particulier dans PostgreSQL.
la source
dsql2('select count(*) from livescreen.'||table_name)
ou mieux à une fonction qui pourrait être transformée.Je ne me souviens pas de l'URL d'où j'ai collecté cela. Mais j'espère que cela devrait vous aider:
L'exécution
select count_em_all();
devrait vous faire compter le nombre de lignes de toutes vos tables.la source
quote_ident(t_name.relname)
) pour assurer une prise en charge appropriée des noms inhabituels ("nom-colonne", par exemple).SELECT * FROM count_em_all() as r ORDER BY r.num_rows DESC;
Deux étapes simples:
(Remarque: pas besoin de changer quoi que ce soit - il suffit de copier-coller)
1. créer une fonction
2. Exécutez cette requête pour obtenir le nombre de lignes pour toutes les tables
ou
Pour obtenir le nombre de lignes dans le tableau
la source
J'ai fait une petite variation pour inclure toutes les tables, également pour les tables non publiques.
utiliser
select count_em_all();
pour l'appeler.J'espère que vous trouverez cela utile. Paul
la source
Cela a fonctionné pour moi
la source
J'aime la réponse de Daniel Vérité . Mais lorsque vous ne pouvez pas utiliser une instruction CREATE, vous pouvez utiliser une solution bash ou, si vous êtes un utilisateur Windows, une PowerShell:
la source
Je voulais le total de toutes les tables + une liste des tables avec leurs nombres. Un peu comme un tableau des performances de l'endroit où le plus de temps a été passé
Vous pouvez bien sûr aussi mettre une
LIMIT
clause sur les résultats dans cette version pour obtenir le plus grandn
délinquants ainsi qu'un total.Une chose à noter à ce sujet est que vous devez le laisser reposer pendant un certain temps après les importations en vrac. J'ai testé cela en ajoutant simplement 5000 lignes à une base de données sur plusieurs tables à l'aide de données d'importation réelles. Il a montré 1800 enregistrements pendant environ une minute (probablement une fenêtre configurable)
Ceci est basé sur https://stackoverflow.com/a/2611745/1548557 travail, donc merci et reconnaissance à cela pour la requête à utiliser au sein du CTE
la source