Azure Sql FreeText (полнотекстовый) поиск невероятно медленный - PullRequest
0 голосов
/ 06 июля 2019

У меня установлен полный текст (по умолчанию) в 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 как для переменных, так и для статических данных, поскольку они имеют точно такой же план.

FREETEXT query execution plan FREETEXT query execution details FREETEXT query execution details

Этот план выполнения LIKE запроса

LIKE query execution plan LIKE query execution details

...