У меня есть сложный запрос с объединением многих таблиц. Из-за сложности сложно поставить реальный запрос.Запрос SQL Server очень медленный, когда число элементов внутри раздела IN более 4
Это что-то вроде
select t1.id, t2.id, t1.name, t2.name
from table1 t1, table2 t2
left join table3 t3 ON t2.id = t3.id
where t2.id = t1.ref_id
and t1.ref_id IN ('id1', 'id2', 'id3', 'id4', 'id5', ...)
я обнаружил, что если у меня есть внутри В статье только 4 или меньше значения, как этого t1.ref_id IN ('id1', 'id2', 'id3', ' id4 '), он работает очень быстро (16 мс). Если я просто добавлю один id и сделаю его 5, как это t1.ref_id IN ('id1', 'id2', 'id3', 'id4', 'id5'), время выполнения увеличивается до 40 раз и становится 600 мс.
Я получил его на SQL Server 2014.
Похоже, есть некоторый параметр, который контролирует это поведение. Я пробовал этот запрос на другом SQL-сервере (SQL Server 2008), и я не мог найти никакого ограничения.
Мой вопрос: Есть ли какой-либо параметр, который контролирует такое поведение? или как увеличить этот странный предел до 50, например.
Я просто хочу увеличить его до 30-50 вместо 4. Конечно, я не хочу создавать предложение IN с сотнями и тысячами значений.
Update1
К сожалению, я забыл поставить t3.name, чтобы выбрать, в противном случае это выглядит как t3 мне не нужно:
select t1.id, t2.id, t1.name, t2.name, t3.name
from table1 t1, table2 t2
left join table3 t3 ON t2.id = t3.id
where t2.id = t1.ref_id
and t1.ref_id IN ('id1', 'id2', 'id3', 'id4', 'id5', ...)
UPDATE2
Похоже, я нашел причину. Проблема была не в количестве элементов внутри IN. Позже я воспроизвел этот вопрос с менее чем 4 идентификаторами (даже с 1). Это происходит, потому что некоторые идентификаторы не были представлены в t1.ref_id. когда были иды, которых нет в t1.ref_id, когда это было быстро, когда я добавил id, который существует в t1.ref_id, когда он становится медленным. В моем предыдущем примере id1 - id4 не был представлен в t1.ref_id и был представлен id5. Поэтому, когда я добавляю id5, он становится медленным. Он становится медленным, даже если я просто поставлю только 1 id (id5) внутри предложения IN. Наконец, индекс t1.ref_id решил проблему. Не было волшебства около 4 или 5 идентификаторов. Это просто совпадение в моем конкретном примере.
Вы создали индекс на t1.ref_id? –
Вы сделали хорошо, чтобы сузить разницу. Теперь сравните планы запросов между медленными и быстрыми версиями. Что ты видишь. Нажмите CTRL-L, чтобы просмотреть планы запросов. –
Вы не должны смешивать неявный и явный синтаксис соединения, вы должны переписать на явный синтаксис. Это стандарт ANSI с 1992 года! Является ли этот запрос частью хранимой процедуры? Помогает ли это, если вы добавляете 'OPTION (RECOMPILE)'? – HoneyBadger