Я пытался COUNT(*)
создать таблицу с 150000 строк, которая имеет первичный ключ. Это инструмент около 5 минут, поэтому я понял, что это проблема индексации.
Ссылаясь на руководство PostgreSQL :
REINDEX похож на удаление и воссоздание индекса в том, что содержимое индекса перестраивается с нуля. Однако соображения блокировки довольно разные. REINDEX блокирует записи, но не чтения родительской таблицы индекса. Он также принимает эксклюзивную блокировку для конкретного обрабатываемого индекса, который блокирует чтения, которые пытаются использовать этот индекс (...). Последующий CREATE INDEX блокирует записи, но не читает; поскольку индекс отсутствует, чтение не будет пытаться его использовать, а это означает, что не будет никаких блокировок, но чтение может быть принудительно выполнено в дорогостоящее последовательное сканирование.
Исходя из собственного опыта, можете ли вы сказать:
- это
REINDEXING
опасно? Может ли это повредить целостность данных? - Может ли это занять много времени?
- Это вероятное решение моего сценария?
Обновить:
Решение, которое работало для нас, было воссоздать тот же индекс с другим именем, а затем удалить старый индекс.
Создание индекса выполняется очень быстро, и мы уменьшили размер индекса с 650 МБ до 8 МБ. Использование COUNT(*)
с between
занимает всего 3 секунды.
источник
COUNT(*)
это лучший выбор:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.
Я не уверен в лучшем ответе для вас. Однако, эта ветка предлагает несколько хороших предложений: npostgresql.1045698.n5.nabble.com/count-performance-issue-td2067873.html
Следует отметить, что вы могли бы реализовать TRIGGER для поддержания количества строк в отдельной таблице (если ваши приложения будут часто вызывать COUNT (*)).
Некоторые ответы предполагают, что это симптоматично для базы данных, которая не была недавно очищена пылесосом (предполагается, что автоочистка отключена на вашем сервере или для этой базы данных в частности)?
Другое предложение выглядит так:
И кто-то, идентифицированный как А. Кречмер, отмечает:
Нет. Текущая реализация индекса не содержит информации о видимости строк в текущей транзакции. Вам необходимо просканировать всю таблицу данных, чтобы узнать, видна ли текущая строка в текущей транзакции.
... поддерживая мой комментарий о том, что разрешения на уровне строк влияют на производительность.
Мой поиск также обнаружил WikiVS: MySQL против PostgreSQL: COUNT (*) .
Вы можете просмотреть другие результаты, которые я нашел с помощью Google: производительность postgresql count (*)
источник