Я выполняю профилирование (SQL Server 2008) некоторых наших представлений и запросов, чтобы определить их эффективность в отношении использования процессора и операций чтения. Я понимаю, что число операций чтения - это число операций чтения логического диска в страницах размером 8 КБ. Но мне трудно определить, чем я должен быть доволен.
Например, когда я запрашиваю одно из наших представлений, которое, в свою очередь, соединяется с другим представлением и имеет три OUTER APPLY с табличными UDF, я получаю значение Reads 321 со значением CPU 0. Моя первая мысль, что я должен быть счастлив с этим. Но как мне оценить значение 321? Это говорит мне, что 2 654 208 байт данных были логически считаны для удовлетворения запроса (который возвратил одну строку и 30 столбцов).
Как некоторые из вас будут определять, достаточно ли это хорошо или требует более тонкой настройки? Какие критерии вы бы использовали?
Кроме того, мне любопытно, что входит в 2 654 208 байт считанных логических данных. Включает ли это все данные, содержащиеся в 30 столбцах в одной возвращенной строке?
2,5 МБ включают все данные на 321 странице, включая другие строки на тех же страницах, которые были получены по вашему запросу. , а также индексные страницы, полученные для поиска ваших данных. Обратите внимание, что это логическое чтение, а не физическое чтение, например. чтение из кэшированной страницы сделает чтение намного «дешевле» - при оптимизации также используйте показатель стоимости ЦП и профилировщика.
В.р.т. Как определить оптимальную «цель» для чтения.
FWIW Я сравниваю фактическое количество прочтений с оптимальным значением, которое я могу представить как минимальное количество страниц, необходимых для возврата данных в вашем запросе в «идеальном» мире.
напр. если вы подсчитаете примерно 5 строк на страницу из таблицы x, а ваш запрос вернет 20 строк, «идеальным» числом операций чтения будет 4, плюс некоторые накладные расходы на навигацию по индексам (при условии, конечно, что строки сгруппированы «идеально» для вашего запрос) - так что утопия будет около 5-10 страниц.
Для запроса, критичного для производительности, вы можете использовать фактическое чтение против «утопического» чтения для микрооптимизации, например:
Вы можете найти эту статью полезно
ХТХ!
321 читает со значением ЦП 0 звучит довольно хорошо, но все зависит от этого.
Как часто выполняется этот запрос? Почему используются пользовательские функции, возвращающие таблицу, а не просто соединения? Каков контекст использования базы данных (сколько пользователей, количество транзакций в секунду, размер базы данных, это OLTP или хранилище данных)?
Чтения дополнительных данных происходят из:
Всех других данных на необходимых страницах для удовлетворения чтений, сделанных в плане выполнения. Обратите внимание, что сюда входят кластеризованные и некластеризованные индексы. Изучение плана выполнения даст вам лучшее представление о том, что именно читается. Вы увидите ссылки на всевозможные индексы и таблицы, а также информацию о том, требовался ли поиск или сканирование. Обратите внимание, что сканирование означает, что была прочитана каждая страница во всем индексе или таблице. Вот почему поиск предпочтительнее сканирования.
Все связанные данные в таблицах INNER JOINd в представлениях, независимо от того, нужны ли эти JOIN для получения правильных результатов для выполняемого вами запроса, поскольку оптимизатор не знает, будут ли эти INNER JOIN исключать/включать строки до тех пор, пока он не СОЕДИНИТ их.
Если вы предоставите запросы и планы выполнения в соответствии с запросом, я, вероятно, смогу дать вам лучший совет. Поскольку вы используете UDF с табличным значением, мне также нужно будет увидеть сами UDF или, по крайней мере, план выполнения UDF (что возможно только путем отрыва его мяса и запуска вне контекста функции или преобразования его в хранимая процедура).