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.

Вы можете найти пример кода C# для заполнения TVP здесь

Если вы хотите производительности, я бы использовал предложение 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 в вашей временной таблице, тогда ваш запрос будет выполняться быстрее.

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