Я намагався COUNT(*)створити таблицю з 150 000 рядків, в якій є Первинний ключ. Це інструмент близько 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.