Очень низкая производительность для внутреннего объединения с ограничительным предложением where (очень маленькое подмножество строк)
У меня есть две большие таблицы, к которым я присоединяюсь, используя промежуточную таблицу отображения (подробности структуры ниже).
Я пытаюсь присоединиться ко всем трем t1.date = t2.date
а также t1.id_a = int.id_a
а также int.id_b = t2.id_b
У меня также есть предложение where, которое ограничивает данные очень конкретным диапазоном столбца даты (результирующий набор составляет ~25 тыс. Строк).
Выполнение соединения таблицы 1 и таблицы int (с предложением where) или объединения таблицы 2 с таблицей int (с предложением where) занимает буквально 2 секунды каждая. Затем должно быть тривиально объединить эти два набора результатов, которые составляют около 37 тыс. Строк для таблицы 1 и 200 тыс. Строк для таблицы 2.
Вместо этого это последовательно занимает 8 минут для этого запроса:
select t1.date, t1.id_b, t1.other_cols, t2.other_cols
from t1
inner join t_int on t1.id_a = t_int.id_a
inner join t_2 on t2.date = t1.date and t2.id_b = t_int.id_b
where t1.date between '2018-10-21' and '2018-12-10'
В предполагаемом (и фактическом) плане выполнения SQL Server говорит, что он будет выполнять:
- поиск по кластерному индексу на t1, поиск моего диапазона дат (стоимость 33%)
- вычислить скаляр t.id_a (стоимость 0%)
- поиск по кластерному индексу на t2, поиск моего диапазона дат (стоимость 33%)
- вложенный цикл для объединения [2] и [3] (стоимость 0%)
- поиск не кластеризованного индекса по t_int, поиск по t_int.id_a = t1.id_a и t_int.id_b = t2.id_b (стоимость 33%)
- вложенный цикл для объединения [4] и [5] (стоимость 0%)
- вычислить скалярное время t.date, t_int.id_b (стоимость 0%)
Table 1:
date,
id_a,
other columns
(3,2 млн строк, дата и id_a - первичный ключ с кластерным индексом)
Table 2:
date,
id_b,
other columns
(18,5 млн строк, дата и id_b - первичный ключ с кластерным индексом)
Картографическая таблица:
id_a,
id_b,
other columns
(35 тыс. Строк, id_b - это первичный ключ с кластерным индексом, дополнительный non_clustered индекс на [id_a, id_b, other_col
])
Других индексов и ограничений нет вообще (кроме упомянутых ограничений первичного ключа).
Я уже перестроил индекс на t2
Может кто-нибудь помочь с тем, что мне нужно сделать?
1 ответ
Я уже перестроил индекс на t2, потому что он был фрагментирован. Но я не перестроил индекс на t1 или t_int, так как они выглядели хорошо.
Благодаря предложению Мохаммада Мохаббати в комментариях я перестроил их все, и теперь запрос выполняется менее чем за 1 секунду.
Таким образом, ответ здесь, который может быть полезен для других с подобными проблемами, это "перестроить все индексы, даже если они выглядят хорошо"