(както е указано, поставям част от коментара си в отговор, тъй като той реши проблема)
Преобразувайте EXISTS изразите в IN изрази.
Това работи по-добре в този случай, тъй като заявката сега ще бъде ефективно оценена от „отвътре навън“, като се започне със заявката, която съдържа вашия най-ограничаващ фактор:търсенето на пълен текст. Тази заявка ще върне малък набор от редове, които могат да бъдат търсени директно срещу първичния ключ на външната заявка (WHERE x in (SELECT X...)), за разлика от извикването на „вътрешната“ заявка веднъж за стойност на външната заявка (или за всички стойности в оригиналния ви случай, ако го чета правилно). Методът EXISTS тук води до вложени цикли (една оценка на една заявка за всяка стойност в друга) срещу IN метода, използващ хеш-съединения (много по-ефективен метод за изпълнение в много, ако не и в повечето случаи.
Забележете, че с метода EXISTS има четири вложени цикъла, които се изпълняват, като всеки се изпълнява поне 3000 пъти. Тази цена се натрупва. Въпреки че не е пряко сравнение, можете да третирате вложените цикли, както бихте направили с циклите FOR в кода на приложението:всеки път, когато извиквате вътрешен цикъл, вашата голяма O оценка се повишава с порядък:O(n) до O(n^ 2) до O(n^3) и т.н.
Hash Join е по-скоро като карта, където два масива се преминават едновременно и се извършва операция и върху двата. Това е грубо линейно (O(n)). Помислете за това, че те са вложени като добавка, така че ще премине O(n) към O(2n) към O(3n) и т.н.
Да, да, знам, че не е съвсем едно и също нещо, но въпросът е, че наличието на множество вложени цикли обикновено показва бавен план на заявка и сравняването на двата стила на голямо О прави разпознаването по-лесно, вярвам.
Вложените цикли и EXISTS не са зли сами по себе си, но за повечето случаи, когато има условие за основен филтър, което в крайна сметка засяга всичко (например търсенето на пълен текст във въпроса), IN израз (или в някои случаи, правилно JOIN) дава много по-ефективен план.