Страницы

25 августа 2014 г.

SQL Server. Заметки по ускорению работы БД. Запросы. Blob и Text поля.

Доброго времени суток.
       Далее речь пойдет о связке SQL Server 2008 и .Net Framework 2.0. Недавно один из клиентов начал жаловаться на то что программа тормозит. Клиент относится к старым, структура БД у него устаревшая, билд устаревший, данных много. Высокая нагрузка обеспечивается большим количеством запросов в БД, растущим количеством данных и не совсем оптимально написанными запросами.
       Итак, т.к. на текущий момент я обладаю небольшим опытом по улучшению производительности - буду немного импровизировать и учиться.
Откопав интернетах статью "Статистика по наиболее тяжелым запросам" я воспользовался приведенным им запросом для получения информации о первых кандидатах для оптимизации.



Начинаем пересматривать запросы. В основном проблемы из-за того что запросы используют только въюхи  (даже там где они не нужны) и LEFT JOIN-ы, хотя получаемые результаты этого явно не требовали. Размеры планов таких просто огромные (из-за въюх и кучи ненужных джойнов).
SET STATISTIC OI ON (То что было вначале). Вот результат по самому тяжелому запросу (тест запроса приводить не буду, т.к. он достаточно громоздкий и не читабельный):

(строк обработано: 6)
Таблица "Worktable". Число просмотров 0, логических чтений 0, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "modelpic". Число просмотров 1, логических чтений 1325, физических чтений 0, упреждающих чтений 0, lob логических чтений 406691, lob физических чтений 0, lob упреждающих чтений 30130.
Таблица "good". Число просмотров 1493, логических чтений 3070, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "modelcalc". Число просмотров 18, логических чтений 11339, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "orderitem". Число просмотров 1, логических чтений 56, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "orders". Число просмотров 0, логических чтений 2, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "system". Число просмотров 2, логических чтений 6, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "constructiontype". Число просмотров 1, логических чтений 2, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "productiontype". Число просмотров 1, логических чтений 16, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "measure". Число просмотров 2, логических чтений 4, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "goodtype". Число просмотров 1, логических чтений 2, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.

6 строк за 24 секунды.

Узкое место в этом запросе: 
Таблица "modelpic". Число просмотров 1, логических чтений 1325, физических чтений 0, упреждающих чтений 0, lob логических чтений 406691, lob физических чтений 0, lob упреждающих чтений 30130.

После оптимизации:
Таблица "modelpic". Число просмотров 6, логических чтений 30, физических чтений 0, упреждающих чтений 0, lob логических чтений 94, lob физических чтений 0, lob упреждающих чтений 0.

6 строк за 1 секунду. 

Оптимизация заключалась с следующем:
Изначально таблица (въюха) view_modelpic, которая содержит в себе рисунок джойнилась следующим образом:

left join view_modelpic mp on oi.idmodel = mp.idmodel and mp.deleted is null and mp.typ = 0        

поле с картинкой выводилось в SELECT и т.к. есть агрегаты - участвовало в группировке. Именно это, по моему мнению, спровоцировало многократное чтение картинки и тормозило запрос. Выход из этой ситуации я нашел в следующем:
Убираем view_modelpic из join-ов и помещаем ее в SELECT в качестве подзапроса:

(SELECT TOP 1 picture FROM view_modelpic WHERE idmodel = oi.idmodel and typ = 0) AS picture,

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

Мораль:
Если есть поля с тяжелыми данными, лучше избегать использования их в группировках и минимизировать количество обращений к записям содержащим такие поля.
SET STATISTIC OI ON Вам в помощ.

Комментариев нет:

Отправить комментарий