У меня установлен полный текст (по умолчанию) в Azure Sql (20 DTU).
У меня есть SP поиска, в котором выполняется поиск по стольким таблицам, и все столбцы, к которым я обращаюсь с помощью FreeText, индексируются.
Этот SP имеет 44 параметра, большинство из которых BIT
типа. Я решаю, следует ли искать в определенных таблицах на основе предоставленных параметров. Итак, я ищу от 1 до 20 таблиц.
Этот SP работает ужасно медленно, я фактически никогда не получаю ответ, когда клиент .net вызывает его (только тайм-ауты), и это когда примерно 10 таблиц запрашиваются (ищутся).
Я выполняю SP в SSMS и наблюдаю, что это занимает столько времени (более 30 секунд), что на локальном компьютере работает менее 1 секунды, как и ожидалось.
Я извлек весь SP в новое окно запроса и запускаю его как запрос (не как SP), и я выполняю поиск только в таблице Users, в то время как весь другой код поддерживает, но не выполняет (это делается установкой related BIT
переменные в 0 (false - BIT)
, поэтому никакая другая таблица не ищется). Однако я также попытался извлечь только часть поискового запроса таблицы пользователей.
Я вставляю поисковый текст вручную в запрос, и он работает быстро (0 мс), как и ожидалось, а для использования переменной требуется 2-4 секунды.
Обратите внимание, что в таблице Users у меня только 180 (да, сто восемьдесят) строк.
У меня есть поисковая текстовая переменная, определенная как DECLARE @SearchText NCHAR(50)
. Оба столбца Name
и LastName
в таблице Users
равны NCHAR(50)
.
Это медленный (2-4 секунды) запрос:
SELECT
U.Id AS UserId
, @SearchType AS MatchType
FROM
Users U WITH (NOLOCK)
WHERE
(
FREETEXT(U.[Name], @SearchText)
OR
FREETEXT(U.[LastName], @SearchText)
)
Это быстрый (0 мс) запрос:
SELECT
U.Id AS UserId
, @SearchType AS MatchType
FROM
Users U WITH (NOLOCK)
WHERE
(
FREETEXT(U.[Name], 'John')
OR
FREETEXT(U.[LastName], 'John')
)
Интересно, что это также быстро (0 мс) :
SELECT
U.Id AS UserId
, @SearchType AS MatchType
FROM
Users U WITH (NOLOCK)
WHERE
(
U.[Name] LIKE '%' + @SearchText + '%'
OR
U.[LastName] LIKE '%' + @SearchText + '%'
)
Сначала я подозреваю parameter sniffing
, но, так как я извлек весь SP, это больше не проблема.
Я пытался использовать пару подсказок отдельно OPTION (RECOMPILE)
, OPTION (OPTIMIZE FOR UNKNOWN)
.
Пока ничего не получалось. Есть что-то, чего я здесь не хватает? Разве FREETEXT
не должен быть молниеносным (по крайней мере, с 180 рядами)?
UPDATE
Это план выполнения поиска FREETEXT
как для переменных, так и для статических данных, поскольку они имеют точно такой же план.
Этот план выполнения LIKE
запроса