Büyük tablolardaki satırları saymanın PostgreSQL'de yavaş olduğu bilinmektedir. Kesin bir sayı elde etmek için, MVCC'nin doğası gereği tam bir satır sayımı yapması gerekir . Sizin durumunuzda olduğu gibi sayımın kesin olması gerekmiyorsa , bunu çarpıcı bir şekilde hızlandırmanın bir yolu var .
Tam sayıyı almak yerine ( büyük tablolarda yavaş ):
SELECT count(*) AS exact_count FROM myschema.mytable;
Bunun gibi yakın bir tahmin elde edersiniz ( son derece hızlı ):
SELECT reltuples::bigint AS estimate FROM pg_class where relname='mytable';
Tahminin ne kadar yakın olduğu, ANALYZE
yeterince koşup koşmamanıza bağlıdır . Genellikle çok yakındır. PostgreSQL Wiki SSS
bölümüne bakın .
Veya count (*) performansı için ayrılmış wiki sayfası .
Daha iyisi
PostgreSQL Wiki makale edilir oldu biraz özensiz . Bir veritabanında - farklı şemalarda - aynı isimde birden çok tablo olma olasılığını göz ardı etti. Bunu hesaba katmak için:
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'
Ya da daha iyisi
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE oid = 'myschema.mytable'::regclass;
Daha hızlı, daha basit, daha güvenli, daha zarif. Nesne Tanımlayıcı Türleri hakkındaki kılavuza bakın .
to_regclass('myschema.mytable')
Geçersiz tablo adlarının istisnalarını önlemek için Postgres 9.4+ ile kullanın :
SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1);
Gibi @a_horse yorumladı , için yeni eklenen fıkra SELECT
istatistik eğer komuta yararlı olabilir pg_class
nedense değil şimdiki yeterlidir. Örneğin:
- Koşmak yok
autovacuum
.
- Hemen sonra büyük
INSERT
veya DELETE
.
TEMPORARY
tablolar (kapsamına girmeyen autovacuum
).
Bu yalnızca rastgele n % ( 1
örnekte) blok seçimine bakar ve içindeki satırları sayar. Daha büyük bir numune maliyeti artırır ve seçiminizdeki hatayı azaltır. Doğruluk daha fazla faktöre bağlıdır:
- Sıra boyutunun dağılımı. Belirli bir blok normal satırlardan daha geniş tutarsa, sayı normalden daha düşüktür vb.
- Ölü demetler veya
FILLFACTOR
blok başına yer kaplar. Tabloya eşit olmayan bir şekilde dağıtılırsa, tahmin yanlış olabilir.
- Genel yuvarlama hataları.
Çoğu durumda, tahmin pg_class
daha hızlı ve daha doğru olacaktır.
Asıl soruya cevap
İlk olarak, bu tablodaki satırların sayısını bilmem gerekiyor, eğer toplam sayı önceden tanımlanmış bir sabitten büyükse,
Ya da ...
... sayım sabit değerimi geçtiği anda mümkündür, saymayı durdurur (ve satır sayısının daha büyük olduğunu bildirmek için saymanın bitmesini beklemeyin).
Evet. Aşağıdakilerle bir alt sorguLIMIT
kullanabilirsiniz :
SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t;
Postgres aslında verilen sınırın ötesinde saymayı durdurur , n satıra kadar (örnekte 500000) kesin ve güncel bir sayım elde edersiniz , aksi takdirde n . Yine de tahmin edilen kadar hızlı değil .pg_class