Вопросы о производительности многостоловых запросов

Существует два способа выполнения многостоловых запросов:

Запрос 1:

select t1.a, t2.b from t1, t2 where t1.a = t2.a

Запрос 2:

для каждого ряда:

select t1.a from t1

сделать еще один запрос:

select t2.b from t2 where t2.a = '??'

какая из них имеет лучшую производительность, когда таблица очень большая?

1 ответ

Решение

Вы всегда должны позволять СУБД выполнять как можно больше работы за один запрос.

СУБД знает, сколько существует кортежей в каждой базе данных, и может оценить количество кортежей, которое будет иметь результат. Современные СУБД имеют очень сложные алгоритмы, которые отвечают за поиск наиболее эффективного способа выполнения любого запроса (планировщик).

Если вы не знаете, что вы делаете, и почему вы это делаете (то есть вы знаете, что ваш алгоритм будет работать быстрее, чем СУБД, и, что более важно, почему), вы просто должны позволить DMBS выполнять свою работу.

Точнее ответить на ваш вопрос:

На ваш запрос № 1 можно ответить различными способами, в зависимости от размера таблиц. Давайте предположим, что оба ОГРОМНЫ. Один из способов решить эту проблему - использовать объединение на основе сортировки: вы сортируете обе таблицы на основе атрибута объединения, а затем объединяете их. Это будет в основном эквивалентно времени, необходимому для выполнения сортировки слиянием в каждой таблице. Каждая страница каждой таблицы будет прочитана и записана несколько раз (в зависимости от того, сколько буферного пространства у вас есть в DMBS). Таким образом, каждый кортеж в T1 и T2 будет читаться / записываться, скажем, дюжину раз.

Если мы реализуем ваш метод, будет столько же запросов, сколько кортежей размером T1. Предположим, что T2 не имеет индекса, поэтому запрос будет читать каждый кортеж за T2 T1 раз.

Если у вас есть индекс на T2, вы можете ожидать, что для каждого кортежа в T1 будет прочитано несколько страниц. Таким образом, стоимость вашего запроса - это стоимость чтения T1, а затем для каждого кортежа в T1 вам нужно прочитать несколько страниц (2-5), чтобы найти соответствующие кортежи в T2.

Если T1 очень маленький, а T2 очень большой, запрос 2 будет быстрее! Но СУБД обнаружит это и выполнит ТОЧНО ваш алгоритм для ответа на вопрос Q1 (это называется объединением на основе цикла). Кроме того, каждый запрос, который вы отправляете в СУБД, требует времени для обработки (накладные расходы, которых нет у метода 1).

Это распространенная ошибка наивного программиста СУБД: пусть БД выполняет небольшую работу, а затем для каждого кортежа - еще немного.

Вместо этого вам следует подумать о том, чтобы позволить СУБД выполнять всю обработку в минимально возможном количестве запросов. Это окупится в исполнении.

Наконец, если вы действительно заинтересованы в производительности, возьмите документацию вашей любимой DMBS и прочитайте, как она выполняет оценку запросов и как ее улучшить.

--dmg

Другие вопросы по тегам