Il conteggio delle righe in tabelle di grandi dimensioni è noto per essere lento in PostgreSQL. Per ottenere un numero preciso, è necessario eseguire un conteggio completo delle righe a causa della natura di MVCC . C'è un modo per accelerare drasticamente questo se il conteggio non deve essere esatto come sembra essere nel tuo caso.
Invece di ottenere il conteggio esatto ( lento con tavoli grandi):
SELECT count(*) AS exact_count FROM myschema.mytable;
Ottieni una stima ravvicinata come questa ( estremamente veloce ):
SELECT reltuples::bigint AS estimate FROM pg_class where relname='mytable';
Quanto è vicina la stima dipende dal fatto che corri ANALYZE
abbastanza. Di solito è molto vicino.
Vedi le FAQ sul Wiki di PostgreSQL .
Oppure la pagina wiki dedicata per il conteggio (*) delle prestazioni .
Meglio ancora
L'articolo nel Wiki di PostgreSQL è stato un po 'sciatto . Ha ignorato la possibilità che ci possano essere più tabelle con lo stesso nome in un database - in schemi diversi. Per tenere conto di ciò:
SELECT c.reltuples::bigint AS estimate
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'mytable'
AND n.nspname = 'myschema'
O meglio ancora
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE oid = 'myschema.mytable'::regclass;
Più veloce, più semplice, più sicuro, più elegante. Vedere il manuale sui tipi di identificatori di oggetti .
Utilizzare to_regclass('myschema.mytable')
in Postgres 9.4+ per evitare eccezioni per nomi di tabelle non validi:
SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1);
Come ha commentato @a_horse , la clausola appena aggiunta per il SELECT
comando potrebbe essere utile se le statistiche in pg_class
non sono abbastanza aggiornate per qualche motivo. Per esempio:
- Nessuna
autovacuum
corsa.
- Subito dopo un grande
INSERT
o DELETE
.
TEMPORARY
tabelle (che non sono coperte da autovacuum
).
Questo guarda solo una selezione casuale n % ( 1
nell'esempio) di blocchi e conta le righe in essa. Un campione più grande aumenta il costo e riduce l'errore, scegli tu. La precisione dipende da più fattori:
- Distribuzione delle dimensioni delle righe. Se un determinato blocco contiene righe più larghe del normale, il conteggio è inferiore al normale ecc.
- Tuple morte o uno
FILLFACTOR
spazio di occupazione per blocco. Se distribuito in modo non uniforme sulla tabella, la stima potrebbe non essere valida.
- Errori di arrotondamento generali.
Nella maggior parte dei casi la stima da pg_class
sarà più veloce e più accurata.
Risposta alla domanda effettiva
Innanzitutto, ho bisogno di conoscere il numero di righe in quella tabella, se il conteggio totale è maggiore di una costante predefinita,
E se è ...
... è possibile nel momento in cui il conteggio supera il mio valore costante, interromperà il conteggio (e non vedo l'ora di finire il conteggio per informare che il conteggio delle righe è maggiore).
Sì. Puoi utilizzare una sottoquery conLIMIT
:
SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t;
Postgres interrompe effettivamente il conteggio oltre il limite dato, ottieni un conteggio esatto e corrente fino a n righe (500000 nell'esempio) e n altrimenti. Non così veloce come la stima in pg_class
, però.