Могут ли таблицы, организованные по индексу, проложить путь для более быстрого ВЫБОРА COUNT (*) ИЗ таблицы

StackOverflow https://stackoverflow.com/questions/839015

Вопрос

Я нахожу громоздким создавать триггер только для получения текущего общего количества строк таблицы, не выполняя COUNT(*) ИЗ таблицы.Я думаю, могли бы ли их запланированные таблицы с индексной организацией для Postgres 8.5 сделать это возможным?

Это было полезно?

Решение

Я бы не подумал, что таблица с индексами обязательно будет быстрее сканировать, чтобы подсчитать все видимые кортежи. По логике вещей, ему придется проходить одинаковый объем данных, независимо от того, организованы ли они так, что данные находятся в конечных узлах b-дерева или в существующем формате кучи.

В настоящее время индексы postgresql хранят только пары [key, ctid] (по существу). (Ctid - это, по сути, «rowid» - номер страницы кучи и индекс указателя строки кортежа). Таким образом, вы не можете сосчитать строки в таблице, просто пройдя по индексу, потому что вам нужно проверять [xmin, xmax] для каждого tuple-- и это сохраняется только с данными в куче.

Вы также можете поместить [xmin, xmax] в указатель - время от времени предлагать предложения для этой обрезки. Но это раздувает индексы, и для того, чтобы все обновления / удаления были полезными, они должны были бы быть в курсе того, что они были в актуальном состоянии: и это вызывает проблемы, не в последнюю очередь потому, что работа, связанная с обновлением, теперь увеличилась на некоторое количество, умноженное по количеству показателей на столе. В случае значительных индексов, таких как tsvector, или индексов, основанных на дорогостоящих пользовательских выражениях, это может занять некоторое время, а в некоторых неприятных случаях вообще не работает, поскольку строки теперь кажутся живыми в индексе, но мертвыми в куча. И весь смысл этого упражнения должен был состоять в том, чтобы позволить базе данных полагаться исключительно на информацию о живом существовании в индексе, если это возможно. Эта стоимость будет понесена, даже если вы обновляете неиндексированный столбец - то, что команда приложила некоторые усилия для ускорения в 8.3 (кортежи только для кучи).

Я полагаю, что одной из возможностей было бы отметить индексы как необязательно имеющие [xmin, xmax] - например, пометьте только индекс pkey таким образом. Тогда нужно было бы внести изменения в планировщик, чтобы понять, когда это было преимуществом - похоже, довольно много работы.

Упорядоченные по индексу таблицы, если они работают так, как я полагаю, работают в Oracle (и SQL Server, где любая таблица с кластеризованным индексом в основном организована по индексу), работают вместо хранения [key, tuple] в индексе первичного ключа. (и, предположительно, [ключ, pkey] во всех остальных) - нет ctid, нет кучи. Так что "кортеж" будет содержать [xmin, xmax, cminmax, natts, ....] и т. д., и вы можете выполнить команду «выбрать количество (*) из таблицы»; просто сканируя индекс. Но это, по сути, то же самое, что сканирование кортежей в куче - они волшебным образом не занимают меньше места, потому что теперь они в индексе.

AFAICT главная причина организованной по индексу таблицы заключается в том, что небольшая таблица с одним индексом первичного ключа займет 1 страницу вместо 3, а сканирование индекса по первичному ключу может быть немного быстрее. Кажется, я помню, что совет, связанный с Oracle, который мне дали для IOT, заключался в том, что они предназначались для таблиц статических измерений, а не для общего назначения, отчасти из-за затрат на поддержание вторичных индексов (я не думаю, что хранилища Oracle [ key, pkey] во вторичных индексах IOT, а скорее в качестве альтернативного rowid).

Другие советы

Это устарело, но с PostgreSQL 9.2 вы получаете сканирование только по индексу, которое также может выполнять count (*).

Смотрите также,

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top