Очень низкая производительность для внутреннего объединения с ограничительным предложением 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 говорит, что он будет выполнять:

  1. поиск по кластерному индексу на t1, поиск моего диапазона дат (стоимость 33%)
  2. вычислить скаляр t.id_a (стоимость 0%)
  3. поиск по кластерному индексу на t2, поиск моего диапазона дат (стоимость 33%)
  4. вложенный цикл для объединения [2] и [3] (стоимость 0%)
  5. поиск не кластеризованного индекса по t_int, поиск по t_int.id_a = t1.id_a и t_int.id_b = t2.id_b (стоимость 33%)
  6. вложенный цикл для объединения [4] и [5] (стоимость 0%)
  7. вычислить скалярное время 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 секунду.

Таким образом, ответ здесь, который может быть полезен для других с подобными проблемами, это "перестроить все индексы, даже если они выглядят хорошо"

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