Я обычно переписываю подобные запросы, чтобы избежать ...
Not In - это ужасно для производительности, хотя Not Exists улучшает это.
Ознакомьтесь с этой статьей, http://www.sql -server-pro.com / sql-where-clause-optim.html
Мое предложение ...
Выделите ваш столбец pkey в рабочую / временную таблицу, добавьте столбец (флаг) int default 0, не ноль, и индексируйте столбец pkey. Отметьте флаг = 1, если запись существует в вашем подзапросе (намного быстрее!).
Замените ваш sub select в вашем основном запросе существующим где (выберите pkey из temptable, где flag = 0)
То, что это работает, - это возможность создать список значений «не существует», которые можно использовать включительно из набора «все включено».
Вот наш общий набор.
{1,2,3,4,5}
Вот существующий набор
{1,3,4}
Мы создаем наш рабочий стол из этих двух наборов (технически левое внешнее соединение)
(Запись: существует)
{1: 1, 2: 0, 3: 1, 4: 1, 5: 0}
Наш набор «несуществующих записей»
{2,5} (выберите *, где флаг = 0)
Наш продукт ... и намного быстрее (индексы!)
{1,2,3,4,5} в {2,5} = {2,5}
{1,2,3,4,5} нет в {1,3,4} = {2,5}
Это можно сделать без рабочего стола, но его использование упрощает визуализацию происходящего.
Kris