Я вижу странное поведение со следующим запросом T-SQL в SQL Server 2012:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
Только выполнение этого запроса дает мне около 1300 результатов менее чем за две секунды (включен полнотекстовый индекс Name
)
Однако, когда я изменяю запрос на это:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
OFFSET 0 rows
FETCH NEXT 10 ROWS ONLY
Требуется больше 20 секунд, чтобы дать мне 10 результатов.
Следующий запрос еще хуже:
SELECT Id
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY Name) AS RowNum, Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"') ) AS RowConstrainedResult
WHERE RowNum >= 0 AND RowNum < 11
ORDER BY RowNum
Это займет более 1,5 минут!
Есть идеи?
SELECT TOP 10 * .... ORDER BY Name
?Ответы:
Поскольку вы просто хотите
TOP 10
упорядочить по имени, он думает, что будет быстрее обработать индекс поname
порядку и посмотреть, соответствует ли каждая строкаCONTAINS(Name, '"John" AND "Smith"') )
предикату.Предположительно, чтобы найти 10 требуемых совпадений, требуется намного больше строк, чем он ожидает, и эта проблема кардинальности усугубляется количеством ключевых поисков.
Быстрый хак , чтобы остановить его , используя этот план будет изменить ,
ORDER BY
чтобыORDER BY Name + ''
хотя использованиеCONTAINSTABLE
в сочетании сFORCE ORDER
также должны работать.источник
Это похоже на классическую неправильную оценку избирательности. Не уверен, что с этим можно сделать, так как «драйвером» запроса является полнотекстовый поиск, который нельзя дополнить статистикой.
Попробуйте переписать
where contains
предикат вinner join containstable
( CONTAINSTABLE ) и применить подсказки порядка соединения, чтобы изменить форму плана.Это не идеальное решение, потому что у него есть проблемы с техническим обслуживанием, но я не вижу другого пути.
источник
Мне удалось решить проблему:
Как я уже сказал в этом вопросе, для всех столбцов были индексы + статистика для каждого столбца. (Из-за устаревших запросов LIKE) Я удалил все индексы и статистику, добавил полнотекстовый поиск и вуаля, запрос стал действительно быстрым.
Кажется, показатели привели к другому Плану выполнения.
Спасибо всем большое за вашу помощь!
источник