Determinar el número de filas en PostgreSQL

Como suelo olvidar con facilidad ciertas cosas y al no usar mucho del.icio.us para recordarlas, pongo aquí un artículo que encontré hace unos días por si alguien más le encuentra utilidad. 😉

En cualquier gestor de base de datos, para conocer el número de registros basta con hacer uso de la función de agregación count.

sql:
SELECT count(*) FROM tabla;

Pero hacer esta operación en PostgreSQL sobre tablas grandes es bastante costosa porque se realiza un recorrido secuencial para obtener el número exacto de registros.

code:
test=> EXPLAIN ANALYZE SELECT COUNT(*) FROM actor;
                                               QUERY PLAN
---------------------------------------------------------------------------------------------------------
 Aggregate  (cost=4.50..4.51 rows=1 width=0) (actual time=0.882..0.884 rows=1 loops=1)
   ->  Seq Scan on actor  (cost=0.00..4.00 rows=200 width=0) (actual time=0.011..0.432 rows=200 loops=1)
 Total runtime: 0.963 ms
(3 filas)

Una forma de obtener el número aproximado de registros de manera rápida y sin los problemas inherentes al uso de la función count, es haciendo una consulta a los catálogos del sistema (pg_class):

sql:
SELECT reltuples FROM pg_class
   JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid)
WHERE nspname = 'public' -- esquema
AND relname = 'actor'; -- nombre de la tabla

Para que lo anterior funcione o dé resultados más cercanos a la realidad, es necesario ejecutar ANALYZE sobre esa tabla, tarea que se debe realizar periódicamente.

3 Replies to “Determinar el número de filas en PostgreSQL”

  1. La solución me gusta, pero hay un leve problema, y es que no estaria actualizado constantemente, aunque si ayuda y mucho para tablas que no se actualizan mucho pero que aun asi son bastante grandes.

    umm se me ocurre algo, no seria mas facil crear un trigger que se lance un insert incremente y cuando se lance un delete decremente un valor en una tabla de tamaños?, solo habria que inicializarlo de la siguiente forma una tabla que contuviese dos valores el primer valor de la columna se corresponderia con el nombre de la tabla y en el segundo una columna numerica

  2. Perdón quería decir que se lanzase en el evento insert y delete, y bueno puedo equivocarme porque ultimamente en casa manejo tanto MySQL como PostgreSQL y en el curro Oracle y puede que me confunda y el tema de los trigers sea propio de Oracle pero lo dudo imagino que ambos tanto MySQL como PostgreSQL tienen dicha funcionalidad.

    seria algo tan sencillo como actualizar dicha tabla con un update cada vez que se hace un insert o un delete.

  3. Juanjo, realizar ANALYZE sobre las tablas es vital para que se escojan de mejor manera los planes de ejecución y por consiguiente se consiga un mejor desempeño en las consultas que se hacen sobre éstas.

    It is a good idea to run ANALYZE periodically, or just after making major changes in the contents of a table. Accurate statistics will help the planner to choose the most appropriate query plan, and thereby improve the speed of query processing. A common strategy is to run VACUUM and ANALYZE once a day during a low-usage time of day

    Sobre el trigger, ciertamente funcionaría, pero crearía una sobrecarga más en las inserciones y eliminaciones.

Comments are closed.