Hay tres formas de obtener este tipo de conteo, cada una con sus propias compensaciones.
Si desea un recuento verdadero, debe ejecutar la instrucción SELECT como la que utilizó en cada tabla. Esto se debe a que PostgreSQL mantiene la información de visibilidad de la fila en la fila misma, no en ningún otro lugar, por lo que cualquier recuento exacto solo puede ser relativo a alguna transacción. Obtiene un recuento de lo que ve esa transacción en el momento en que se ejecuta. Puede automatizar esto para que se ejecute en cada tabla de la base de datos, pero probablemente no necesite ese nivel de precisión o no quiera esperar tanto.
El segundo enfoque señala que el recopilador de estadísticas rastrea aproximadamente cuántas filas están "activas" (no eliminadas u obsoletas por actualizaciones posteriores) en cualquier momento. Este valor puede estar un poco apagado bajo actividad intensa, pero generalmente es una buena estimación:
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
Eso también puede mostrar cuántas filas están muertas, lo cual es un número interesante para monitorear.
La tercera forma es tener en cuenta que el comando ANALIZAR del sistema, que se ejecuta regularmente mediante el proceso de vacío automático a partir de PostgreSQL 8.3 para actualizar las estadísticas de la tabla, también calcula una estimación de fila. Puedes agarrarlo así:
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;
Es difícil decir cuál de estas consultas es mejor usar. Normalmente tomo esa decisión en función de si hay más información útil que también quiero usar dentro de pg_class o dentro de pg_stat_user_tables. Para propósitos básicos de conteo solo para ver cuán grandes son las cosas en general, cualquiera de los dos debe ser lo suficientemente preciso.
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
? Mi base de datos Redshift carece de esa columna. Es un derivado de Postgres 8.0.2.pg_stat_user_tables
) me devolvió la mayoría de los cerosn_live_tup
porqueANALYZE
nunca se había ejecutado. En lugar de ejecutarANALYZE
en cada esquema / tabla y esperar una respuesta para siempre, primero verifiqué los resultados usando 'tercer enfoque' y ese (usandopg_class
) devolvió conteos muy precisos.Aquí hay una solución que no requiere funciones para obtener un recuento preciso para cada tabla:
query_to_xml
ejecutará la consulta SQL pasada y devolverá un XML con el resultado (el recuento de filas para esa tabla). El exteriorxpath()
extraerá la información de conteo de ese xml y la convertirá en un número.La tabla derivada no es realmente necesaria, pero hace que sea
xpath()
un poco más fácil de entender; de lo contrario, todo sequery_to_xml()
tendría que pasar a laxpath()
función.fuente
query_to_jsonb()
.select count(*)
en cada mesa.xpath()
función solo se aplica a una sola fila - el resultado decount(*)
Para obtener estimaciones, vea la respuesta de Greg Smith .
Para obtener recuentos exactos, las otras respuestas hasta ahora están plagadas de algunos problemas, algunos de ellos serios (ver más abajo). Aquí hay una versión que es de esperar mejor:
Toma un nombre de esquema como parámetro, o
public
si no se proporciona ningún parámetro.Para trabajar con una lista específica de esquemas o una lista que proviene de una consulta sin modificar la función, se puede invocar desde una consulta como esta:
Esto produce una salida de 3 columnas con el esquema, la tabla y el recuento de filas.
Ahora, aquí hay algunos problemas en las otras respuestas que esta función evita:
Los nombres de tablas y esquemas no deben inyectarse en SQL ejecutable sin ser citados, ya sea con
quote_ident
o con laformat()
función más moderna con su%I
cadena de formato. De lo contrario, una persona malintencionada puede nombrar su tabla,tablename;DROP TABLE other_table
que es perfectamente válida como nombre de tabla.Incluso sin la inyección de SQL y los problemas de caracteres divertidos, el nombre de la tabla puede existir en variantes que difieren según el caso. Si se nombra una tabla
ABCD
y otraabcd
,SELECT count(*) FROM...
debe usar un nombre entre comillas; de lo contrario, se saltaráABCD
y contaráabcd
dos veces. El%I
formato de hace esto automáticamente.information_schema.tables
enumera los tipos compuestos personalizados además de las tablas, incluso cuando table_type es'BASE TABLE'
(!). Como consecuencia, no podemos repetirinformation_schema.tables
, de lo contrario corremos el riesgo de tenerselect count(*) from name_of_composite_type
y eso fallaría. OTOHpg_class where relkind='r'
siempre debería funcionar bien.El tipo de COUNT () es
bigint
, noint
. Pueden existir tablas con más de 2.15 mil millones de filas (sin embargo, ejecutar un conteo (*) es una mala idea).No es necesario crear un tipo permanente para que una función devuelva un conjunto de resultados con varias columnas.
RETURNS TABLE(definition...)
Es una mejor alternativa.fuente
Si no le importan los datos potencialmente obsoletos, puede acceder a las mismas estadísticas utilizadas por el optimizador de consultas .
Algo como:
fuente
ANALYZE
sobre la mesa, las estadísticas pueden desviarse. Es una cuestión de carga de la base de datos y cómo se configura la base de datos (si las estadísticas se actualizan con más frecuencia, las estadísticas serán más precisas, pero podrían reducir el rendimiento del tiempo de ejecución). En definitiva, la única forma de obtener datos precisos es ejecutarselect count(*) from table
todas las tablas.La respuesta arrogante y práctica para las personas que intentan evaluar qué plan de Heroku necesitan y no pueden esperar a que se actualice el contador lento de heroku:
Básicamente desea ejecutar
\dt
enpsql
, copiar los resultados a su editor de texto favorito (que se verá así:), luego ejecute una búsqueda de expresiones regulares y reemplace así:
a:
lo que te dará algo muy similar a esto:
(Deberá eliminar el último
union
y agregar el punto y coma al final manualmente)Ejecútalo
psql
y listo.fuente
select '$1', count(*) from $1 union/g
/g
(conservarunion
) y agregar un punto y coma (;
) al final. No olvides eliminar el últimounion
antes del punto y coma.union
antes del punto y coma" es lo que quise decir :) Agregué la palabra "último" para aclararloNo estoy seguro de si una respuesta en bash es aceptable para usted, pero FWIW ...
fuente
select count(*) from table_name;
en el OP!Por lo general, no confío en las estadísticas, especialmente en PostgreSQL.
fuente
dsql2('select count(*) from livescreen.'||table_name)
o mejor, podría convertirse en una función propia.No recuerdo la URL de donde recolecté esto. Pero espero que esto te ayude:
La ejecución
select count_em_all();
debería obtener el recuento de filas de todas sus tablas.fuente
quote_ident(t_name.relname)
) para garantizar el soporte adecuado para nombres inusuales ("nombre de columna", por ejemplo).SELECT * FROM count_em_all() as r ORDER BY r.num_rows DESC;
Dos pasos simples:
(Nota: no es necesario cambiar nada, solo copie y pegue)
1. Crear función
2. Ejecute esta consulta para obtener el recuento de filas para todas las tablas
o
Para obtener filas cuenta por tabla
fuente
Hice una pequeña variación para incluir todas las tablas, también para tablas no públicas.
solía
select count_em_all();
llamarlo.Espero que encuentres esto útil. Pablo
fuente
Esto funciono para mi
fuente
Me gusta la respuesta de Daniel Vérité . Pero cuando no puede usar una instrucción CREATE, puede usar una solución bash o, si es un usuario de Windows, una de PowerShell:
fuente
Quería el total de todas las tablas + una lista de tablas con sus recuentos. Un poco como un gráfico de rendimiento donde se pasó la mayor parte del tiempo
Por supuesto, también podría poner una
LIMIT
cláusula sobre los resultados en esta versión para obtener losn
delincuentes más grandes , así como un total.Una cosa que debe tenerse en cuenta al respecto es que debe dejarlo reposar durante un tiempo después de las importaciones a granel. Probé esto simplemente agregando 5000 filas a una base de datos en varias tablas usando datos de importación reales. Mostró 1800 registros durante aproximadamente un minuto (probablemente una ventana configurable)
Esto se basa en https://stackoverflow.com/a/2611745/1548557 trabajo, así que gracias y reconocimiento por la consulta que se utilizará dentro del CTE
fuente