SQL Server 2005 FREETEXT () Проблема производительности - PullRequest
4 голосов
/ 28 мая 2010

У меня есть запрос с 6-7 объединенными таблицами и предикатом FREETEXT () для 6 столбцов базовой таблицы в каталоге where.

Теперь этот запрос работал отлично (менее чем за 2 секунды) за последний год и практически не изменился (я пробовал старые версии, и проблема сохраняется)

Итак, сегодня один и тот же запрос неожиданно занимает около 1-1,5 минуты.

После проверки плана выполнения в SQL Server 2005, перестройка индекса FULLTEXT этой таблицы, реорганизация индекса FULLTEXT, создание индекса с нуля, перезапуск службы SQL Server, перезапуск всего сервера. Не знаю, что еще делать попробовать.

Я временно переключил запрос на использование LIKE, пока не выясню это (сейчас это занимает около 6 секунд).

Когда я смотрю на запрос в анализаторе производительности запросов, когда я сравниваю запрос «FREETEXT» с запросом «LIKE», первый имеет в 350 раз больше операций чтения (4921261 против 13943) и 20 раз (38937 против . 1938) загрузка процессора последним.

Так что это действительно предикат «FREETEXT», который делает его таким медленным.

У кого-нибудь есть идеи по поводу причины? Или дальнейшие тесты, которые я мог сделать?

[Изменить]

Ну, я просто снова запустил запрос, чтобы получить план выполнения, и теперь он снова занимает 2-5 секунд, без каких-либо изменений, хотя проблема все еще существовала вчера. И это не было связано с какими-либо внешними факторами, поскольку я прекратил доступ всех приложений к базе данных при первом тестировании проблемы в прошлый четверг, поэтому это не было связано с какими-либо другими нагрузками.

Хорошо, я все равно включу план выполнения, хотя это может не сильно помочь теперь, когда все снова работает ... И будьте осторожны, это огромный запрос к устаревшей базе данных, который я не могу изменить (т.е. нормализовать данные или избавиться от ненужных промежуточных таблиц)

План запроса

хорошо, вот полный запрос

Возможно, мне придется объяснить, что именно это делает. в основном он получает результаты поиска объявлений о работе, где есть два типа объявлений, премиум и обычные. результаты разбиты на страницы до 25 результатов на страницу, до 10 премиальных вверх и 15 обычных после этого, если их достаточно.

так что есть два внутренних запроса, которые выбирают столько премиум / нормальных, сколько необходимо (например, на странице 10 он выбирает первые 100 премиальных и 150 лучших), затем эти два запроса чередуются с помощью команды row_number () и немного математики. затем комбинация упорядочивается по rownumber и возвращается запрос. Ну, он используется в другом месте, чтобы просто получить 25 объявлений, необходимых для текущей страницы.

Да, и весь этот запрос построен в ОГРОМНОМ устаревшем файле Coldfusion, и, поскольку он работал нормально, я не осмеливался до сих пор обрабатывать / изменять большие порции ... никогда не трогать работающую систему и т. Д .;) Просто маленький такие вещи, как изменение битов центрального предложения where.

Файл также генерирует другие запросы, которые делают в основном то же самое, но без различия между премией и не премиумом и множеством других вариантов этого запроса, поэтому я никогда не уверен, как изменение одного из них может изменить другие ...

Хорошо, поскольку проблема больше не всплыла, я дал Мартину награду, поскольку он был самым полезным на данный момент, и я не хотел, чтобы награда истекала без необходимости. Спасибо всем за их усилия, я попробую ваши предложения, если это произойдет снова:)

Ответы [ 2 ]

1 голос
/ 31 мая 2010

Эта проблема может возникнуть из-за плохой оценки количества результатов, которая будет возвращена полнотекстовым запросом, что приведет к плохой стратегии для операций JOIN.

Как вы находите производительность, если разбить ее на 2 шага?

Один новый шаг, который заполняет временную таблицу или табличную переменную результатами полнотекстового запроса, а второй изменяет существующий запрос, чтобы вместо этого ссылаться на временную таблицу.

(NB. Возможно, вы захотите попробовать это СОЕДИНЕНИЕ с и без OPTION(RECOMPILE), просматривая планы запросов для (A) условия поиска в виде свободного текста, которое возвращает много результатов (B), которое возвращает только несколько результатов.

Редактировать Трудно уточнить точно в отсутствие оскорбительного запроса, но я имею в виду вместо выполнения

SELECT <col-list>
FROM --Some 6 table Join
WHERE FREETEXT(...);

Как это работает?

DECLARE @Table TABLE
(
<pk-col-list>
)
INSERT INTO @Table
SELECT PK
FROM YourTable
WHERE FREETEXT(...)

SELECT <col-list>
FROM --Some 6 table Join including onto @Table
OPTION(RECOMPILE)
0 голосов
/ 03 июня 2010

Обычно, когда у нас возникает эта проблема, это происходит из-за фрагментации таблицы и устаревшей статистики по рассматриваемым индексам.

В следующий раз попробуйте EXEC sp_updatestats после перестроения / переиндексации.

Подробнее см. Использование статистики для улучшения производительности запросов .

...