Длинные запросы
и соединения хешированием
105
рот: индексы не нужны, а если таблицы проиндексированы, надо убедиться,
что индексы не используются.
Почему для длинных запросов предпочтительно полное сканирование
таблицы? Как показано на рис. 3.1, когда количество
необходимых строк
достаточно велико, для индексного доступа потребуется больше операций
ввода-вывода. Какой процент или количество записей является «достаточно
большим», варьируется и зависит от множества разных факторов. К настоя-
щему времени вас не должно удивлять, что в большинстве случаев PostgreSQL
вычисляет этот процент верно.
В главе 5 похожие слова были сказаны и о коротких запросах. Но «до-
статочно велико» труднее оценить, чем «достаточно мало». Оценка этой
верхней границы меняется по мере развития и
улучшения аппаратного
обеспечения, дисков и процессоров. По этой причине в книге мы стараемся
не указывать конкретные числа пороговых значений, которые со временем
обязательно изменятся. Чтобы привести показательные примеры для этой
главы, мы создали несколько таблиц с сотнями миллионов строк данных.
Они слишком велики, чтобы включать их в дистрибутив
postgres_air
. Одна-
ко мы не удивимся, если через пару лет для некоторых примеров не хватит
и этого размера.
д
линные
заПросы
и
соединения
хешированием
В большинстве примеров этой главы используется алгоритм соединения
хешированием, и именно его мы надеемся
увидеть в плане выполнения
длинного запроса. Почему соединение хешированием в данном случае пред-
почтительнее? В главе 3 мы вычислили стоимость алгоритмов вложенного
цикла и соединения хешированием.
Для вложенного цикла стоимость соединения таблиц
R
и
S
составляет
cost(nl,R,S) = size(R)*size(S) + size(R)*size(S)/size(JA)
Для соединения хешированием:
cost(hash,R,S) = size(R) + size(S) + size(R)*size(S)/size(JA)
Здесь
JA
обозначает количество различных значений атрибута соедине-
ния. Как уже упоминалось в главе 3,
слагаемое, соответствующее размеру
результирующего множества, нужно добавить к стоимости обоих алгорит-
мов. Но для алгоритма вложенного цикла это значение значительно меньше,
чем стоимость самого соединения. Для длинных запросов размер таблиц
R
и
S
больше (потому на них не накладываются значительные ограничения),
поэтому стоимость вложенных циклов значительно
превышает стоимость
соединения хешированием.
Если у нас есть таблица
R
с 1 000 000 строк и таблица
S
с 2 000 000 строк, а
JA
имеет 100 000 различных значений, стоимость алгоритма вложенного цикла
будет равна 2 000 020 000 000, а стоимость алгоритма соединения хеширова-
нием составит 23 000 000.
106
Длинные запросы и полное сканирование
Соединения хешированием работают лучше всего, когда первый аргумент
помещается в оперативную память. Размер доступной
памяти можно на-
строить с помощью параметров сервера.
В некоторых случаях используется алгоритм соединения слиянием, как по-
казано, например, на рис. 6.10 далее в этой главе. В главе 3 мы упоминали, что
соединение слиянием может быть более эффективным, если по крайней мере
одна из таблиц была предварительно отсортирована. В этом примере, посколь-
ку выбираются уникальные значения, фактически выполняется сор тировка.
Подводя итоги главы 5 и этой главы, в большинстве случаев индексный до-
ступ работает хорошо с алгоритмом вложенного цикла (и наоборот), а после-
довательное сканирование хорошо работает с соединением хешированием.
Почему в PostgreSQL нет подсказок оптимизатору?
Есть ли способ при-
нудительно использовать определенный алгоритм соединения? Как уже не-
однократно упоминалось, лучшее, что мы можем сделать, – не ограничивать
оптимизатор при написании инструкций SQL.
Do'stlaringiz bilan baham: