SQL, пытаясь избавиться от больших IN cluase
У меня есть стол,
Contacts:
Contact_ID (int)
ContactName (nvarchar)
Мне дают список идентификаторов контактов для выбора. Обычно я бы просто
SELECT *
FROM Contacts
WHERE IN (List of contact ID)
Проблема в том, что список идентификаторов контактов может стать очень большим, например, 50 КБ или более.
Итак, мой вопрос: есть ли способ справиться с большим списком идентификаторов контактов, не используя предложение IN?
РЕДАКТИРОВАТЬ: я использую Microsoft SQL Server. Запрос и идентификаторы контактов создаются во время выполнения и передаются в класс sqlCommand (C#) для выполнения.
3 ответа
Я бы создал тип таблицы с одним столбцом и кластеризованным первичным ключом.
CREATE TYPE dbo.ContactId AS TABLE
(
ContactId INT NOT NULL PRIMARY KEY
);
Передайте значения в запрос, используя параметр с табличным значением.
Измените ваш запрос на
SELECT *
FROM Contacts
WHERE contactID IN (SELECT y.contactID FROM @yourtablevaluedparameter y)
OPTION (RECOMPILE)
OPTION (RECOMPILE)
нужно учитывать количество строк, так как оптимальный план для 50К может быть иным, чем для 1.
Если вы хотите производительности, я бы использовал предложение EXISTS.
SELECT c.Contact_ID, c.ContactName
FROM Contacts c
WHERE EXISTS (List of contact ID)
Создайте временную таблицу и заполните свой контактный идентификатор в виде строк. Сделайте внутреннее соединение между вашей таблицей и временной таблицей, как показано ниже.
SELECT c.*
FROM Contacts c
join #temptable t
on c.id=t.id
Если вы введете индекс для столбца Join в вашей временной таблице, тогда ваш запрос будет выполняться быстрее.