2010-05-28 5 views
4

У меня есть запрос с примерно 6-7 связанными таблицами и предикатом FREETEXT() на 6 столбцах базовой таблицы в где.SQL Server 2005 FREETEXT() Perfomance Issue

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

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

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

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

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

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

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

[Редактировать]

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

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

Query plan

ки вот полный query

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

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

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

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

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

+0

Можете ли вы опубликовать план выполнения? Проблема, вероятно, в том, что Мартин предложил, и в этом случае может потребоваться повторный порядок запроса с FORCE ORDER. –

+0

Странно. Я полагаю, что вы используете тот же самый поисковый запрос FreeText, который был ранее проблематичным, и что ничто не меняется в данных (например, процесс архивирования), что может привести к сокращению числа совпадающих записей из части FREETEXT за одну ночь? –

+0

Кроме того, если вам удастся решить проблему повторно, можете ли вы использовать параметр «Включить фактический план выполнения» в Management Studio и сохранить это как * .sqlplan (формат XML)? –

ответ

1

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

Как найти работу, если вы разбили ее на 2 шага?

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

(NB:. Вы можете попробовать это JOIN и без 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

Что вы подразумеваете под «Как вы находите производительность, если вы разбиваете ее на 2 шага?» ? Это не имеет смысла для меня в текущем контексте. Я выложу план выполнения завтра на работе, но это огромный запрос (разбиение на страницы с рулонами на два соединенных подзапроса и множество подключений), так что там определенно будет много возможной настройки производительности. Но, как я уже сказал, мне интересно, почему требуется примерно в 50 раз больше времени, чтобы выполнить внезапно, когда запрос был последний раз изменен более месяца назад (добавлено дополнительное предложение where) и работал до конца дня до 4 дней назад ... – Zenon

+0

Возможно, вам нужно будет увидеть план запроса, чтобы угадать это. –

+0

ok Я попробовал его с помощью «DECLARE @ Table» и «OPTION (RECOMPILE) », и это занимает 3 секунды, равно как и исходный запрос. Но мне придется протестировать его, когда проблема снова возникнет. Кстати, когда я удаляю ограничения для поиска только активных (status = 3) строк из запроса, поэтому, чтобы искать все строки (примерно миллион) вместо 19'000 строк, запрос по-прежнему занимает 3 секунды, поэтому Я сомневаюсь, что это связано с тем, что за последние 3 дня некоторые записи базы данных были неактивными. – Zenon

0

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

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

См. Using Statistics to Improve Query Performance для получения дополнительной информации.

+0

Да, это тоже возможно, но это не объяснит, почему он работает для запроса LIKE, который отключается от той же статистики. –

+0

FREETEXT и LIKE используют разные статистические данные, я полагаю (FEETEXT рассматривается как удаленный источник, по сравнению с фактической статистикой индекса для LIKE). – GalacticJello

+0

Исправить. FREETEXT в SQL2005 не имеет статистических данных для оценки каких-либо показателей мощности и не будет затронута sp_updatestats (всегда предполагается, что будет возвращена 1 строка), поэтому предложение в моем ответе на его разделение. Таким образом, точка, которую я делал, заключается в том, что было бы странно (хотя возможно), что запрос, который больше полагался на статистику, не сталкивался с той же проблемой. –