Корреляция имеет смысл только для столбцов с типом данных, который имеет общее упорядочение, то есть поддерживает семейство операторов , которое относится к методу доступа btree
(операторы <
, <=
, =
, >=
и >
).
Корреляция положительна, если большие значения имеют тенденцию появляться вблизи физического конца таблицы, а небольшие значения - вблизиначало.Значение 1 означает, что значения хранятся в таблице в отсортированном порядке, -1 означает, что они хранятся в порядке убывания.
Сканирование индекса в PostgreSQL работает следующим образом:
Первая подходящая запись находится в индексе.
Если карта видимости указывает, что соответствующий блок таблицы содержиттолько кортежи, которые видны всем и , нам не нужен столбец, который не хранится в индексе, у нас есть результат и мы продолжаем с шага 4 (если оптимизатор считает, что это работает для большинства записей индекса, он будетпланировать сканирование только по индексу ).
Соответствующая строка выбирается из таблицы и проверяется на видимость.Если он виден и удовлетворяет условию фильтра, мы нашли результат.
просматривают индекс в направлении сканирования, чтобы найти следующую запись индекса и посмотреть, удовлетворяет ли он условию сканирования.Если да, вернитесь ко второму шагу, иначе мы закончили.
Это вызывает случайное чтение блоков таблицы, если они уже не находятся в общих буферах.
Теперь, если корреляция высокая, более вероятно, что произойдут две вещи:
Следующий кортеж, найденный при сканировании индекса, находится в том же блоке таблицы, что и предыдущий кортеж,Тогда он уже находится в общих буферах и не вызывает чтения.
В итоге вы получите меньше отдельных блоков таблиц: элементы индекса рядом друг с другом, как правило, тоже близки друг к другучасто в одном и том же блоке.
Если следующая индексная запись не указывает на тот же блок таблицы, что и предыдущий, она, вероятно, будет указывать на следующий блок таблицы.Это приводит к последовательному чтению блоков таблицы, что на вращающихся дисках более эффективно, чем случайное чтение.
Позвольте мне проиллюстрировать это на примере, предполагая индекс для идеально коррелированного столбца:
Первая найденная запись индекса указывает на блок таблицы 42, вторая тоже, с третьей на 30-ю точку указывает на блок 43, следующие 20 записей индекса будут указывать на блок 44.
Таким образом, сканирование индекса посетит 50 кортежей, но будет считывать только 3 блока с диска, и они будут читать их в последовательном порядке (сначала блок 42, затем блок 43, затем блок 44).
Если не былокорреляция, 50 кортежей, вероятно, будут находиться в разных блоках таблицы (при условии, что таблица большая), что будет означать 50 случайных операций чтения с диска.
Таким образом, сканирование индекса дешевле при высокой корреляции, а сканирование обратного индексадешевле, если корреляция низкая.Оптимизатор использует корреляцию для соответствующей корректировки предполагаемых затрат.