Когда я объединяю два условия в предложении WHERE моего запроса, для выполнения требуется более минуты. Если я разделился на два разных запроса, они оба работают примерно через 1 секунду.SQL - ИЛИ заставляет запрос работать очень медленно
Любые мысли? Смотрите ниже:
Это занимает более чем минута
SELECT
COUNT(b.BookKey)
from
Books b (nolock)
inner join BookPublishCities bp (nolock)
on b.BookKey = bp.BookKey
where
contains(bp.PublishRegionName, @SearchTerm) OR contains(b.BookTitle, @SearchTerm)
Вместе они составляют около 1 вторых
SELECT
COUNT(b.BookKey)
from
Books b (nolock)
inner join BookPublishCities bp (nolock)
on b.BookKey = bp.BookKey
where
contains(bp.PublishRegionName, @SearchTerm)
-- and...
SELECT
COUNT(b.BookKey)
from
Books b (nolock)
inner join BookPublishCities bp (nolock)
on b.BookKey = bp.BookKey
where
contains(b.BookTitle, @SearchTerm)
- Существует полнотекстовый индекс Books.BookTitle и BookPublishCities.PublishRegionName ,
- Обе таблицы содержат около 500 тыс. Строк. Причина, по которой я не включил PublishRegionName в таблицу Books, состоит в том, что вам разрешен только один полнотекстовый индекс для каждой таблицы.
- Существует индекс на BookPublishCities.BookKey
Я просто не знаю, почему отдельные запросы намного быстрее. Мысли?
Возможный дубликат [Полнотекстового поиска SQL Server значительно снижается при использовании «ИЛИ» в разделе where] (http://stackoverflow.com/questions/4100589/sql- server-full-text-search-performance-dramally-down-when-using-or-in-whe) –
Спасибо @rtumaykin. Можете ли вы дать подробную информацию о 2-м ответе в этой должности? «Реальная проблема заключается в том, что с помощью« ИЛИ »на месте нельзя выбрать правильный индекс, поскольку« правильный »индекс будет зависеть от результата первой оценки для каждой отдельной строки. Поэтому СУБД выбирает один индекс (скорее всего, правильная для первой части «OR»), и в случае, если первая оценка возвращается как «ложная», запускает вторую, неиндексированную, что замедляет работу. Производительность для этого во многом зависит от того, насколько часто первые оценки возвращает «false». – Ricky
Не видя планов исполнения, на самом деле не так много догадываться. Оптимизатор пытается выбрать баланс между оптимальным планом выполнения и не тратить слишком много времени на его создание. Я могу думать о 3 возможных проблемах: 1. Оптимизатор отказывается от OR и прибегает к полному сканированию таблицы. 2. Оптимизатор имеет план выполнения кэширования, который был создан на основе @SearchTerm, который был законно быстрее выполнить с использованием полного scan, и теперь он просто повторно использует его 3. Оптимизированное решение о том, что стоимость OR превышает порог параллелизма и пытается выполнить запрос с использованием нескольких параллельных потоков. –