Есть три способа получить такой счет, каждый со своим собственным компромиссом.
Если вам нужен истинный счет, вы должны выполнить оператор SELECT, подобный тому, который вы использовали для каждой таблицы. Это связано с тем, что PostgreSQL хранит информацию о видимости строк в самой строке, а не где-либо еще, поэтому любой точный счет может быть только относительно некоторой транзакции. Вы получаете счет того, что видит эта транзакция в тот момент, когда она выполняется. Вы можете автоматизировать это для запуска каждой таблицы в базе данных, но вам, вероятно, не нужен такой уровень точности или вы хотите ждать так долго.
Второй подход отмечает, что сборщик статистики отслеживает, сколько строк «живое» (не удалено или не устарело при последующих обновлениях) в любое время. Это значение может быть немного занижено при высокой активности, но обычно это хорошая оценка:
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
Это также может показать количество мертвых строк, что само по себе является интересным числом для мониторинга.
Третий способ - отметить, что системная команда ANALYZE, которая регулярно выполняется процессом автовакуума с PostgreSQL 8.3 для обновления статистики таблицы, также вычисляет оценку строки. Вы можете взять это так:
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;
Трудно сказать, какой из этих запросов лучше использовать. Обычно я принимаю это решение, основываясь на том, есть ли еще полезная информация, которую я также хочу использовать внутри pg_class или внутри pg_stat_user_tables. Для основных целей подсчета, просто чтобы увидеть, насколько большие вещи в целом, либо должны быть достаточно точными.
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
? В моей базе данных Redshift отсутствует этот столбец. Это производная от Postgres 8.0.2.pg_stat_user_tables
) вернулn_live_tup
мне в основном нули , потому чтоANALYZE
он никогда не выполнялся. Вместо того, чтобы запускатьANALYZE
каждую схему / таблицу и ждать ответа вечно, я сначала проверил результаты, используя «третий подход», и тот (с использованиемpg_class
) дал очень точные результаты.Вот решение, которое не требует функций для получения точного подсчета для каждой таблицы:
query_to_xml
выполнит переданный запрос SQL и вернет XML с результатом (количество строк для этой таблицы). Затем внешнийxpath()
извлечет информацию о количестве из этого xml и преобразует ее в числоПроизводная таблица на самом деле не нужна, но
xpath()
немного облегчает понимание - в противном случае целоеquery_to_xml()
должно быть переданоxpath()
функции.источник
query_to_jsonb()
.select count(*)
на каждом столе.xpath()
функция применяется только к одной строке - результатcount(*)
Чтобы получить оценки, см . Ответ Грега Смита .
Чтобы получить точные подсчеты, другие ответы до сих пор страдают от некоторых проблем, некоторые из которых серьезные (см. Ниже). Вот версия, которая, надеюсь, лучше:
Это берет имя схемы как параметр, или
public
если параметр не указан.Чтобы работать с конкретным списком схем или списком, полученным из запроса, без изменения функции, его можно вызвать из запроса, например:
Это приводит к выводу трех столбцов со схемой, таблицей и количеством строк.
Теперь в некоторых ответах есть некоторые проблемы, которых эта функция избегает:
Имена таблиц и схем не следует вставлять в исполняемый SQL без кавычек, ни с помощью,
quote_ident
ни с более современнойformat()
функцией со%I
строкой формата. В противном случае злоумышленник может назвать свою таблицу,tablename;DROP TABLE other_table
которая является абсолютно допустимой в качестве имени таблицы.Даже без инъекций SQL и проблем с забавными символами, имя таблицы может существовать в разных вариантах. Если таблица именована
ABCD
и еще однаabcd
,SELECT count(*) FROM...
необходимо использовать имя в кавычках, иначе оно будет пропущеноABCD
и посчитаноabcd
дважды.%I
Формат делает это автоматически.information_schema.tables
перечисляет пользовательские составные типы в дополнение к таблицам, даже если table_type равен'BASE TABLE'
(!). Как следствие, мы не можем повторятьinformation_schema.tables
, иначе мы рискуем,select count(*) from name_of_composite_type
и это потерпит неудачу. OTOHpg_class where relkind='r'
всегда должен работать нормально.Тип COUNT () есть
bigint
, а неint
. Могут существовать таблицы с более чем 2,15 миллиардами строк (хотя подсчет (*) для них - плохая идея).Не требуется создавать постоянный тип для функции, возвращающей набор результатов с несколькими столбцами.
RETURNS TABLE(definition...)
это лучшая альтернатива.источник
Если вы не возражаете против потенциально устаревших данных, вы можете получить доступ к той же статистике, которая используется оптимизатором запросов. .
Что-то вроде:
источник
ANALYZE
по таблице, статистика может оказаться далеко. Это вопрос загрузки базы данных и того, как база данных настроена (если статистика обновляется чаще, статистика будет более точной, но это может снизить производительность во время выполнения). В конечном счете, единственный способ получить точные данные - это запуститьselect count(*) from table
для всех таблиц.Хакерский, практичный ответ для людей, пытающихся оценить, какой план Heroku им нужен, и не может дождаться обновления медленного счетчика строк Героку:
В основном вы хотите запустить
\dt
вpsql
, копировать результаты в вашем любимом текстовом редакторе (это будет выглядеть следующим образом :), затем запустите поиск по регулярному выражению и замените его следующим образом:
чтобы:
что даст вам нечто очень похожее на это:
(Вам нужно будет удалить последний
union
и добавить точку с запятой в конце вручную)Запустите его,
psql
и все готово.источник
select '$1', count(*) from $1 union/g
/g
(сохранитьunion
) и добавить одну точку с запятой (;
) в самом конце. Не забудьте убрать последнийunion
перед точкой с запятой.union
перед точкой с запятой» - вот что я имел в виду :) Добавил слово «последний», чтобы уточнитьНе уверен, что ответ в bash приемлем для вас, но FWIW ...
источник
select count(*) from table_name;
в ОП!Я обычно не полагаюсь на статистику, особенно в PostgreSQL.
источник
dsql2('select count(*) from livescreen.'||table_name)
или лучше, ее можно превратить в собственную функцию.Я не помню URL, откуда я это собрал. Но надеюсь, это поможет вам:
Выполнение
select count_em_all();
должно дать вам количество строк всех ваших таблиц.источник
quote_ident(t_name.relname)
), чтобы обеспечить надлежащую поддержку необычных имен (например, «имя-столбца»).SELECT * FROM count_em_all() as r ORDER BY r.num_rows DESC;
Простые два шага:
(Примечание: не нужно ничего менять - просто скопируйте и вставьте)
1. Создайте функцию
2. Запустите этот запрос, чтобы получить количество строк для всех таблиц
или
Чтобы получить количество строк в табличном виде
источник
Я сделал небольшой вариант, чтобы включить все таблицы, в том числе и для закрытых.
использовать,
select count_em_all();
чтобы позвонить.Надеюсь, вы найдете это полезным. Павел
источник
Это сработало для меня
источник
Мне нравится ответ Даниэля Верите . Но когда вы не можете использовать оператор CREATE, вы можете использовать либо решение bash, либо, если вы пользователь Windows, - PowerShell:
источник
Я хотел, чтобы итог от всех таблиц + список таблиц с их количеством. Немного похоже на график производительности, где было потрачено больше всего времени
Вы, конечно, могли бы также включить
LIMIT
пункт о результатах в этой версии, чтобы получить как наибольшее количествоn
нарушителей, так и общее количество.Одна вещь, на которую следует обратить внимание, это то, что вам нужно немного подождать после массового импорта. Я проверил это, просто добавив 5000 строк в базу данных в нескольких таблицах, используя реальные данные импорта. Он показывал 1800 записей в течение минуты (вероятно, настраиваемое окно)
Это основано на работе https://stackoverflow.com/a/2611745/1548557 , так что спасибо вам и признание за запрос, который будет использоваться в CTE
источник