Я пытался 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.