2015-08-28 2 views
2

У меня есть таблица,SQL, пытаясь избавиться от большого IN cluase

Contacts: Contact_ID (int) ContactName (nvarchar)

Я дал список контактных идентификаторов, чтобы выбрать из. Как правило, я бы просто сделать

SELECT * 
FROM Contacts 
WHERE IN (List of contact ID) 

Проблема заключается в том, что в списке контактных идентификаторов потенциально может получить очень большой, как 50k или более.

Итак, мой вопрос: есть ли способ иметь дело с большим списком идентификаторов контактов без использования предложения IN?

EDIT: Я использую сервер SQL. Запрос и идентификаторы контактов создаются во время выполнения и передаются в класс sqlCommand (C#) для выполнения.

+3

использовать соединение между двумя таблицами и разрешать объединение INNER для устранения записей ... использовать коррелированный подзапрос и предложение «существует» (или подобное в зависимости от РСУБД) (существует *** обычно ***, а затем внутреннее соединение, за которым следует IN), так что RDBMS? и является ли Список идентификаторов контакта в таблице где-нибудь? (не уверен, что вы подразумеваете под «Учитывая список контактов». Вставьте «Список» в временную таблицу и используйте «существует», или внутреннее соединение ... но у этого есть накладные расходы ... чего вы пытаетесь достичь? Просто улучшенная читаемость ? – xQbert

+4

Какая СУБД вы используете? Каждый оптимизатор ведет себя по-другому –

+0

Не уверен, какие СУБД вы находитесь, но большинство из них позволит вам помещать эти ID в временную таблицу и присоединяться к временной таблице. Это, вероятно, будет быстрее. –

ответ

0

Если вы хотите производительность, я бы использовал предложение EXISTS.

SELECT c.Contact_ID, c.ContactName 
FROM Contacts c 
WHERE EXISTS (List of contact ID) 
+1

Непонятно, как OP должен использовать это с «списком идентификаторов контакта». 'IN' и' EXISTS' дают одинаковый план на SQL Server в любом случае (в отличие от 'NOT IN' vs' NOT EXISTS') –

+0

Извините, но когда я ответил, он не дал много информации о своей проблеме. –

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) находится там, чтобы получить количество строк, учитываемые в качестве оптимального плана 50K также может быть иным, чем для 1

You can find some example C# code for populating a TVP here

+0

Создание другой таблицы может быть путем. Я сейчас тестирую это решение. Дам вам знать! благодаря! – Vibol

0

Создайте временную таблицу и введите идентификатор контакта в виде строк. Сделайте внутреннее соединение между таблицей и временной таблицей, как показано ниже.

SELECT c.* 
FROM Contacts c 
join #temptable t 
on c.id=t.id 

Если вы вводите индекс в столбец Join в вашей таблице темп, ваш запрос будет быстрее.