Як відомо, підрахунок рядків у великих таблицях у PostgreSQL є повільним. Щоб отримати точне число, необхідно виконати повну кількість рядків у зв'язку з характером MVCC . Існує спосіб суттєво прискорити це, якщо підрахунок не повинен бути точним, як здається у вашому випадку.
Замість отримання точного рахунку ( повільно з великими таблицями):
SELECT count(*) AS exact_count FROM myschema.mytable;
Ви отримуєте приблизну оцінку, як це ( надзвичайно швидко ):
SELECT reltuples::bigint AS estimate FROM pg_class where relname='mytable';
Наскільки близька оцінка, залежить від того, чи ANALYZE
достатньо ви біжите . Зазвичай це дуже близько.
Див . Поширені запитання про Wikigre PostgreSQL .
Або спеціальна сторінка вікі для виконання підрахунку (*) .
Ще краще
У статті в PostgreSQL Wiki це було трохи неакуратно . Він ігнорував можливість того, що в одній базі даних може бути кілька однойменних таблиць - в різних схемах. Для обліку цього:
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'
Або ще краще
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE oid = 'myschema.mytable'::regclass;
Швидше, простіше, безпечніше, елегантніше. Дивіться посібник про типи ідентифікаторів об'єктів .
Використовуйте to_regclass('myschema.mytable')
в Postgres 9.4 і новіших версій, щоб уникнути винятків для недійсних імен таблиць:
SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1);
Як і прокоментував @a_horse , щойно доданий пункт для SELECT
команди може бути корисним, якщо статистика в pg_class
чомусь недостатня в поточному режимі. Наприклад:
- Не
autovacuum
працює.
- Відразу після великого
INSERT
або DELETE
.
TEMPORARY
таблиці (які не охоплені autovacuum
).
Це враховує лише випадковий n % ( 1
у прикладі) вибір блоків та підрахунок рядків у ньому. Більш великий зразок збільшує вартість і зменшує помилку, ваш вибір. Точність залежить від більшої кількості факторів:
- Розподіл розміру рядків Якщо в даному блоці трапляється ширше звичайних рядків, кількість нижче, ніж зазвичай тощо.
- Мертві кортежі або
FILLFACTOR
займають простір на блок. Якщо нерівномірно розподілено по таблиці, оцінка може бути вимкнена.
- Загальні помилки округлення.
У більшості випадків оцінка з боку pg_class
буде швидшою та точнішою.
Відповідь на актуальне запитання
По-перше, мені потрібно знати кількість рядків у цій таблиці, якщо загальний підрахунок перевищує деяку заздалегідь задану константу,
І чи це ...
... можливо в момент, коли підрахунок передасть моє постійне значення, він зупинить підрахунок (і не чекатиме закінчення підрахунку, щоб повідомити, що кількість рядків більша).
Так. Ви можете використовувати підзапит зLIMIT
:
SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t;
Постгреси насправді перестають рахувати понад задану межу, ви отримуєте точний та поточний підрахунок до n рядків (500000 у прикладі) та n в іншому випадку. pg_class
Хоча не так швидко, як оцінка в .