Книги, научные публикации Pages:     | 1 | 2 | 3 | 4 |

Microsoft Пусть не иссякнет в Microsoft тот дух товарищества, который возможность единомышленникам из АСЕ Team написать эту книгу. ...

-- [ Страница 3 ] --

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

размером пула осуществляется путем установ ки свойств и max, Это важно, если нужно управ лять размером памяти, используемой Web-уровнем. Если все сес Анализ и настройка производительности Web-уровня пула то запрос на установление дополнительной сессии блокируется до тех пока одна из них не будет осво бождена либо не окончится тайм-аут сессии (по умолчанию равный 15 секундам). В следующем примере обсуж задаются в строке соединения:

Dim strCnStr As String "Data Source & "Integrated "Initial Catalog = 4 Pool & "Max Pool =100" Другое влияющее на производительность, Ч это раз мер пакета. Его стоит увеличить для приложений, работающих с большими полями типа blob или image. Если же передава емых данных невелик, то эффективнее малый размер пакета.

Следующий пример демонстрирует задание значения этого ства в строке соединения:

Dim strCnStr As String = "Data & "Integrated & "Initial Catalog = & "Packet Объект SqICommand Для Web-приложений распространен такой сценарий, как выбор ка/модификация данных из базы. Провайдер данных SQL Server реализует классы и DataAdapter/DataSet, позволяющие выполнять выборку и модификацию данных. Здесь мы лишь кратко рассмотрим о классах SqlDataAdapter/DataSet вы можете прочитать в других источни ках, посвященных непосредственно SqlCommand/DataReader ориентированы на сессии и предостав ляют ряд предназначенных повышения производи тельности приложения, К ним относятся и Execute Reader. Кроме того, класс SqICommand предоставляет метод для данных, возвращае в формате В следующих разделах описаны эти четыре метода и пример использования их в программе (консольное ложение на Программа-пример работает с базой дан ных NorthWind, устанавливаемой по умолчанию одновременно с Microsoft SQL Server.

174 Глава Метод Обычно этот метод применяется для выполнения операций Insert, Update и В этих случаях в клиенту инфор мации наиболее полезными считаются о числе затро нутых строк. метод также работает с сохраненными про цедурами, содержащими параметры/возвращаемые значения, которые могут быть возвращены клиенту. В следую щем примере демонстрируется использование этого метода сохраненной процедуры, число записей о клиентах в таблице Customer базы данных NorthWind:

Imports System Imports Imports ExecuteNonQuery Sub Dim As String = & "Initial & "Integrated Dim As String = Dim As New Dim As New = of customers = End Sub End Метод Этот метод применяют, когда нужно получить с уровня данных единственное значение, например число клиентов или идентифи катор одного клиента. пример кода считывает коли Анализ и настройка Web-уровня записей о клиентах из таблицы базы данных Wind:

System Imports Imports Sub Dim As String = "Data "Initial & "Integrated Dim As String = "select from customers" sqlConn As New Dim As New sqlConn) Dim о As Object= of customers = CType(o, End Sub End Module Метод Данный метод предназначен для когда нужно получить одну строку данных или строк, содержащих большое число колонок. Метод полезен, если вам нужно выполнить толь ко один просмотр полученных данных. В следующем примере из таблицы Customers базы данных считываются идентификаторы, фамилии контактных лиц и номера телефонов клиентов.

Imports System Imports Imports Imports Module ExecuteReader Sub Dim strConnString As String "Data & "Initial _ 176 Глава & "Integrated Dim As String = _ from Dim As New Dim As New Dim As = _ Do _ & _ & _ & ControlChars.Tab _ & Loop End Sub End В тех когда вы уверены, что запрос только один ряд, при данного метода можно задать значение перечислимого типа в качестве параметра:

Dim As SqlDataReader = _ Значения строки могут быть получены по либо по номеру позиции, как показано в предыдущем примере. В об случае использование номера позиции немного повышает производительность. Кроме того, если вам емые типы данных, то добиться производительности можно, используя для получения возвращаемых значений мето ды провайдера данных SQL Server, специально предназначенные этих типов. Таких методов несколько, в том числе и СОВЕТ Старайтесь использовать методы дера данных SQL Server для конкретных типов все гда, когда это возможно.

Анализ и настройка производительности Web-уровня Метод Этот метод полезен, когда данные SQL Server в формате XML. Например, чтобы получить данные в формате XML, оператор SQL можно модифицировать таким образом, чтобы SQL Server возвратил данные в этом формате:

Imports System Imports Imports Imports Module ExecuteXmlReader Sub Main() Dim As String = "Data & "Initial & "Integrated Dim As String = "SELECT & & "phone & "From customers & "FOR AUTO" Dim As New Dim sqlComd As New sqlConn) Dim As = Do While Loop End Sub End Module Типичные лузкие места Web-уровня места на Web-уровне возникают по разным причинам, например из-за проблем конфигурации, недостатка аппаратных плохой архитектуры приложения или неэффективной программной реализации. Для устранения проблем конфигура Глава следует всегда поддерживать и сценарии сборки приложения актуальном состоянии и проверять работос пособность конфигурации, особенно после крупных Эффективное нагрузочное позволяет выяснить, возможно ли масштабировать установив до полнительные аппаратные средства. Если вы масштабировали приложение таким образом, необходимо помнить о недостатке этого метода: будьте готовы к дополнительным усилиям по со провождению оборудования. Масштабирование подробно обсуж дается в конце главы. Предпочтительным же считается выявле ние лузких мест с последующим исправлением или кода программ, Это циклический процесс, который требует тести рования производительности и настройки в течение всего жизнен ного цикла программного обеспечения. В этом разделе мы рассмот рим общие подходы, а также поделимся своим опытом использо вания новых, более эффективных приемов программирования.

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

привели тестирование производительности приложения в среде разработки и получили показатели производитель которые сравнить с в среде эксплуатации. При анализе показателей водительности и журналы вы обратили значительно большие пересылаемых данных при теста в среде эксплуатации. того, показатели способности в среде разработки гораздо Вы что будет наоборот, так как в среде используются лее мощные а сценарии и набор клиентов в обоих Вы чинаете исследовать свой среды эксплуатации выяснения различий в конфигурации эксплуата и тестовой средой и что в файле в среде разработки включены опции Trace и причем это произошло как раз перед тем,. эксплуатационные Анализ и настройка производительности Web-уровня Ограничение размера страницы Одна из наиболее частых причин лузких мест на Ч бесконечная загрузка страниц. Передача на слишком большого данных может вызывать проблемы производи тельности как так и сети. это кажется очевид ным, многие Web-приложения, которые мы стра от больших времен отклика только из-за того, что их стра ницы слишком велики. Не бойтесь разделить содержимое. Это может стоить вашим пользователям лишнего щелчка мышью, но зато запрашиваемые ими данные будут загружаться гораздо быстрее. Вот несколько советов, следуя которым вы обеспечите более короткое время отклика, что наверняка улучшит впечатле ние пользователей от вашего Х если ваше Web-приложение возвращает огромные наборы за писей, попробуйте разбить результаты выборки на страницы;

Х уберите из своего кода и HTML пустые промежутки и коммен тарии, это уменьшит данных, пересылаемых по сети;

Х уберите из таблиц стилей неиспользуемые стили.

Оптимальное использование картинок Оптимизируйте все изображения и их умеренно либо когда это действительно необходимо вашему Web-приложению.

Повторное использование одной и же картинки позволяет сократить число сетевых обменов, так как большинство браузе ров умеют картинку на клиенте, чтобы всякий раз не ее с Web-сервера заново. Одна большая картинка эффективнее, чем несколько маленьких. Часто рекламные кар тинки загружаются в другого сайта, который вам неподконтро лен. В крайних случаях это может вызвать загрузки ва из-за того, что ресурс стал недоступ ным или слишком медленно загружается. Если ваш сайт динамич ный и содержит много графики, стоит разместить динамическое содержимое и изображения на разных соответ ствующим образом настроив каждый из них.

Используйте соглашение об Разработайте соглашение об именовании, походящее для ваше го и обеспечивающее читабельность, стараясь сделать 180 Глава структуру каталогов плоской. короткие каталогам и переменным, применяя сокраще ния всегда, когда возможно. Это сократит объем данных, пере в каждом запросе, что может иметь большое значение, так как часто HTML-страница ссылается на файлы разных типов (картинки, таблицы стилей, исполняющиеся на клиен те и т.п.). Избегайте структуры каталогов, как та, что пока зана следующем содержащем 68 символов:

Сократив длину пути структуре каталогов, вы сэкономите 41 символ только в одном запросе:

Отключение SSL Используйте SSL в Web-приложениях только при необходимости.

свои страницы в режимах с использованием SSL и без него, чтобы определить расходы на шифрование данных.

В общем случае мы обнаруживали 20- или 30-процентное сниже ние производительности при использовании SSL. Правильно орга низовав размещение содержимого своего по разным пап кам, вы сможете включать или отключать SSL на уровне катало гов. В большинстве случаев нет необходимости применять для картинок, таблиц стилей и других типов таких, как сце нарии, исполняющиеся на стороне.

Использование новых возможностей На бойтесь пробовать новые методы и средства программиро вания. Многие новые программирования не только обеспечивают дополнительные функциональные возможности, но и повышают производительность по сравнению с существу ющими. Например, хотя доступен уже достаточ но давно, no-прежнему о коде встречаются вызовы хотя при применении последнего пользовате лям требуется дополнительный сетевой обмен. Мы видали так же много испытывавших проблемы про изводительности из-за работы со строками в циклах. Часто их решения достаточно использовать новый класс который может дать огромный выигрыш Анализ и настройка производительности Web-уровня в при конкатенации большого числа строк в цикле.

Масштабируемость на Web-уровне Масштабируемость Ч это возможность повышения производи тельности системы (сокращение времени отклика или увеличе ние пропускной способности) при установке дополнительных ре сурсов. С точки зрения тестирования производительности это означает установку дополнительных аппаратных средств или пе репроектирование Web-приложения с целью обеспечения эффек тивной работы Web-приложения с большим числом пользовате лей. При обсуждении масштабируемости мы рассмотрим мето дологию, позволяющую определить, когда и как нужно масшта бировать Web-уровень.

Масштабирование вширь, масштабирование вверх или настройка производительности?

Обычно масштабируемость достигается двумя схожими метода ми: масштабированием вширь (scaling out) и масштабированием (scaling up). Эти методы следует использовать только пос ле тестирования производительности и настройки ния. Тестирование производительности выявить луз кие места и ограничения приложения. Настроив вы повысите пропускную способность, снизите время клика или решите обе эти задачи. Теперь мы познакомим вас с определениями, а также с доводами за и против ния вширь, масштабирования вверх и ности.

вширь Масштабирование Web-уровня вширь подразумевает установку дополнительных Web-серверов с целью преодоления лузких мест или выявленных на этом уровне. В результате мас штабирования вширь, если отсутствуют лузкие места, связанные с сетью, SQL-уровнем и другими компонентами за пределами Web-сервера, пропускная способность повышается. Недостатком данного метода считается его дороговизна: расходы на аппарат ные и программные средства, а также на развертывание прило 182 Глава жения площадь помещения, охлаждение и Кроме того, требуется больше персонала для сопровождения и установки продукта.

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

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

Когда масштабировать Web-уровень Частая ошибка при создании и Web-приложения Ч использование для преодоления лузких мест множества аппарат ных средств. Настройка производительности приложения сэко номит вам время и деньги: вы поймете, когда действительно требуется добавлять новые аппаратные средства путем вширь или вверх. В главе 2 описаны этапы определе ния требований к приложению в зависимости от примерного ла пользователей вашего Web-приложением. Далее ется протестировать производительность и настроить Web-при ложение с целью достижения или превышения оценочных критериев. Для определения максимального числа пользователей для конкретного Web-приложени и для планирования увеличения Анализ и настройка аппаратных ресурсов стоит также выполнить анализ стоимости транзакции, описанный в главе 9.

Масштабирование Web-уровня следует проводить только после как выявлены и устранены все иные ограничения произво дительности. Например, если на SQL-уровне количество пользо вателей ограничено теми, с которым в состоянии справиться один то сначала следует решить проблемы SQL. He имеет смысла масштабировать ваш Web-уровень, добавляя новые серверы или устанавливая в старые сервера па мяти и процессоров, если SQL-уровень и так работает на пределе.

Разумная достаточность Х океанские круизы и опре делить, насколько большим чтобы максимум сохранив и ассорти услуг. очень судна закрытыми например через Панамский канал.

Если не на проданы, то на содержание лайнера не Лучшее решение вместимость которого пиковым по числу и размеру воз можно, 5%. Тот же самый принцип применим при рас чете аппаратных средств, необходимых для развер Как масштабируется обеспечения отказоустойчивости и избыточности каждое Web-приложение должно использовать не менее двух Web-сер веров. Избыточность можно обеспечить и на базе единственно го компьютера, но наличие только одного Web-сервера повыша ет уязвимость приложения в случае поломки этого сервера. Про ще всего выполнить установив дополнительные Web-серверы и использовав аппаратно или про граммно реализованный механизм распределения нагрузки.

Программное распределение нагрузки средство распределения нагрузки, разработанное Microsoft, называется Network Load Balancing (NLB). Обычно NLB Глава это наименее дорогой способ распределения нагрузки, исполь зующий сервисы, которые з состав Windows 2000 Advan ced Windows 2000 Data Center Edition и Windows Server. метод годится для большинства и позволяет располагать Web-уровень на нескольких узлах. Подроб ные инструкции и приемы практического применения можно по адресу распределение нагрузки Распределение нагрузки с помощью аппаратных средств счита ется так как вводит от дельный от кода Web-приложения, то есть не ре сурсы Web-сервера. Продукты и решения для аппаратного рас пределения нагрузки предлагаются многими компаниями, таки ми, как Cisco, F5 Labs и Extreme Networks. Подробно об и настройке аппаратных распределения нагрузки расска зано на вышеупомянутых Заключение Ознакомившись с конфигурацией вашего Web-приложения, сле дует выявить лузкие места на Web-уровне. При этом ние профилируют с помощью мониторинга журналов IIS и дан ных System Monitor, а также выявляют места кода, вызывающие задержки и другие проблемы. Для этого предлагаются новые средства трассировки Использование, когда это воз и целесообразно, новых методов и средств, предостав ляемых NET, таких, как кэширование данных, печит значительный выигрыш в производительности.

Глава В главе речь о производительности в отношении к общеязыковой среде (common language Прежде всего Ч об особенностях CLR, которые оказыва ют наибольшее на производительность Web-приложений и о специальных счетчиках производительности, емых для анализа работы стандартного Кроме того, обсуждаются программы, которые Microsoft зует при профилировании управляемого кода: Studio от Compuware и от Xtremesoft.

CLR и производительность CLR представляет компонент Framework, отвечающий за то управление, которое мы подразумеваем, говоря об управ ляемом коде managed code). Для CLR заменяет ядро Windows, обеспечивая такие жизненно важные функции, как загрузку, управление памятью и защитой, обработ ку ошибок, а также средства, необходимые для беспрепятствен ного с другими компонентами и приложениями.

Кроме выполнения классической исполняющей среды, CLR также осуществляет компиляцию.NET-приложений именно в той системе, в они выполняются.

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

Microsoft Language Самое главное отличие традиционных от.NET-npu в том, что последние не компилируются напрямую з родной код того процессора, на котором они в ко нечном итоге будут выполняться. Взамен этого они ются с любых языков, (например, Visual Basic C + + или в язык MSIL (Microsoft Intermediate Language], после чего упаковываются и распространяются G виде сборок Ч файла набора файлов, содержащих скомпилированные з язык а также описывающих их (manifest).

Примечание Для просмотра содержимого сборки предназначен инструмент который Micro soft вместе с Framework.

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

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

Компилятор по требованию никогда не исполняется. Исполняется код, сгенерированный встроенным з CLR компилятором, который на зывается по требованию Compiler, JIT).

Как правило, код компилируется только по необходимости. В том случае когда процесс первый раз обращается к методу, в дело вступает JIT и компилирует метод. (Если позднее другое прило жение или копия этого же приложения обратится к этому мето ду, они будут вынуждены аналогичным образом скомпилировать Анализ производительности управляемого кода себе собственную копию метода.) Одной из частей этого процес са является при удостоверяется безопасности т. е. в том, что он обращается только к тем объектам в памяти, которые для этого предназначены. После того как код скомпилирован, исполнение с адреса, где расположен сгенерированный машинный код. Наконец, после процесса сгенерированный код уничтожается.

Такой подход дает огромное преимущество в производительно сти по сравнению с классическими Web-приложениями, написан ными с использованием ASP. ASP go сих пор является интерпре тируемым языком, что подразумевает дополнительные затраты на интерпретацию изначального кода. ASP не преобразует этот код более рационально скомпилированную форму аналогично как это делает Тем не менее при сравнении с классическими скомпилированны приложениями все не столь ясно. Компиляция кода в период выполнения вместо улучшения явно оказывает сильное влияние на производительность. Microsoft приняла меры для минимизации этого влияния, и в некоторых случаях код, по средством JIT, даже превосходит свой неуправляемый аналог.

Единственным преимуществом компиляции кода во время ты является то, что во время выполнения о рабочей среде изве стно много больше, чем разработчик вообще может узнать о во время проектирования. В некоторой степени код при пиляции удается оптимизировать, зная число процессоров и их возможности, а также имея сведения о наличии других систем ных ресурсов и о том, как они в это время С другой стороны, возможности оптимизации ограничены: она имеет смысл тогда, когда затраченное на нее мень ше того выигрыша, который она дает. Признавая это, JIT реали зует определенные алгоритмы, чтобы избежать оптимизаций, которые, вероятно, не сэкономят время, эквивалентное по за тратам затраченным усилиям.

Примечание Если вы хотите узнать точное количе ственное определение влияния JIT на то найдете ряд полезных счетчиков про изводительности в Глава Возможность предварительной компиляции В Framework инструмент ngen.exe, который для компиляции сборок с языка MSIL в машинный код зо время их установки. Этот процесс называется компиляцией На первый взгляд пред компиляция кажется лучшим вариантом: зачем ком пилировать во время работы, если компилятор может успешно пользоваться знаниями об особенностях системы и при установке?

Но дело в том, что компиляции по требованию сказыва ется при загрузке приложения. Поскольку Web-приложения редко перезагружаются перезагружаются то осо бого смысла в компиляции нет. Еще одна при чина отказа от компиляции заключается в том, что в этом случае нельзя оптимизировать систему на основе све дений о ее состоянии во время ее работы.

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

Текущая версия этим не пользуется, но после дующие будут пользоваться и, возможно, сделают предварительную компиляцию более подходящей для Web приложений.

Жизненный цикл Web-приложения Теперь, после того как вы познакомились с мы расскажем, ким еще образом CLR влияет на производительность приложения в различных фазах его выполнения. Имейте в виду, что посколь ку речь идет о то не имеет значения, на каком из высоко уровневых языков написаны компоненты приложения Ч для CLR они представляют либо управляе мые написанные на MSIL, либо неуправляемый код, ра ботающий вне Период загрузки Ч домены приложения CLR загружает приложения в специальные, выделенные для них зоны памяти, называемые доменами приложения (AppDomains), Поскольку CLR обеспечивает типовую безопасность в памяти, Анализ производительности управляемого кода одного домена могут благополучно мно гие приложения. Приложения, находящиеся в домене, представляют единую функциональную группу, поскольку способны быстро и эффективно разделять данные. Кроме того, все приложения и сборки одновременно выгружаются из доме на при его выгрузке.

Период выполнения Ч взаимодействие В период выполнения способно обращаться к неуправляемому коду, например к и к стан дартным DLL Windows. раз, когда исполнение потока затра гивает и код, говорят, что имел мес то переход. С такими переходами связаны определенные затраты.

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

Примечание Например, ресурсоемким гом считается обработка строк, которые часто не обходимо преобразовать в другие форматы, мер в ANSI и Unicode.

Еще одна издержка перехода касается диспетчера памяти CLR, известного как сборщик мусора. (Сборщик мусора более подроб но будет обсуждаться далее в Всякий раз при пере ходе к неуправляемому коду CLR приходится идентифицировать все объекты неуправляемого кода, к которым происходит щение. Это необходимо для того, чтобы сборщик мусора не уда лил эти объекты и, таким образом, не нарушил работу неуправ ляемого потока. Объекты, идентифицированные как возможно используемые неуправляемым кодом, (pinned).

Примечание наиболее благоприятное функционирование приложения это минимум Глава необходимых выполнения данной работы. Используйте при тестировании счетчик # of CLR для поис ка зон, в которых потоки приложения осуществля ют многократный переход между режимами и до его возвращения практически бездействуют.

Период выполнения Ч сбор мусора Одна из наиболее значимых CLR Ч кое управление более известное как сбор мусора. Раз работчику нет необходимости свое собственное управление поскольку автоматически выделяет память для при их создании и периодически просмат ривает, какие объекты используются з данный мо мент. Более неиспользуемые объекты помечаются как мусор и удаляются, а занимаемая ими память освобождается для новых объектов.

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

Практика показала, что подавляющее большинство объектов обычно нужны лишь в течение короткого промежутка времени.

это, сборщик мусора распределяет объекты по трем ка тегориям, или поколениям, с номерами 0, 1 и 2. Каждое поколе ние имеет достаточный размер, который определяет общее чис ло байт, доступное данного поколения. Эти размеры ме няются во время выполнения приложения, но их значения, как приблизительно составляют 256 кбайт, Мбайт и для нулевого, первого и второго со ответственно.

Самыми младшими считаются объекты нулевого поколения. В это поколение помещаются все объекты, заново созданные жением. Если места для размещения объекта в поколении недо статочно, начинается сбор мусора. При этом каждый объект про веряется на предмет использования. Объекты, еще востребован ные, переходят в первое поколение (их пережившими Анализ производительности управляемого кода сбор). Более не нужные уничтожаются. Заметьте: непо средственно после такой процедуры куча нулевого поколения все пуста, таким образом, в есть место для раз мещения нового объекта, кроме случаев, когда система испыты вает нехватку памяти, о чем будет рассказано ниже.

Примечание У вас может возникнуть вопрос: что произойдет если объект окажется настолько большим, что его размер превысит все свободное пространство кучи нулевого Дело в том, размером более 20 кбайт в специальную, предназначенную только них называемую кучей больших объектов. В объекте Memory вы найдете счетчики производи тельности для слежения за размером кучи больших объектов.

Перемещая в первое поколение, сборщик мусора про веряет, ли в нем свободное место. Если это так, то, выпол нив сбор в нулевом поколении, сборщик прекратит рабо ту. Однако, если размер перемещаемых объектов превысит раз кучи этого поколения, то сбор мусора аналогичным образом производится и здесь. Как и в предыдущем случае, более не нуж ные объекты будут а переводятся во второе поколение. Заметьте, что после сбора мусора в куче пер вого поколения находятся лишь объекты, недавно перемещенные из нулевого поколения.

освобождения пространства под новые объекты второе по коление, аналогично первому, также подвергается сбору мусора.

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

Непосредственно после сбора содержимое кучи перегруппирует ся таким образом, чтобы объекты занимали смежные области памяти. Такую кучу называют уплотненной.

192 Глава Имейте Б виду: если сбор в первом поколении, то он и в нулевом поколении. же раз, когда сбор мусора затрагивает и второе поколение, что сборщик мусора сделал полный проход, так как сбор произошел во всех поколениях.

До тех пор пока во сбора необходимо перемещать несколько объектов, процедура считается Ч при работе освобождает наибольший памяти.

Для поддержания работы в сборщике мусора дусмотрена возможность саморегулировки, с помощью которой изменяются размеры младших куч в соответствии с интенсивно стью перемещения объектов. А именно: если из одной кучи в другую перемещается слишком много увеличивается размер кучи, что снижает необходимую периодичность сбора. Если же, наоборот, объекты практически не покидают ее размеры уменьшаются и за счет снижения рабочего набора приложения производительность Единственным исключением второе поколение: поскольку объекты из него не сборщик мусора может увеличивать его размер по мере заполнения. Если же размер кучи второго поколения данного приложения неуклонно увеличивается в ние длительного промежутка времени, это, сигнал к тому, чтобы проанализировать приложение на предмет уменьше ния жизни объектов. Если поколение второго уровня не способно принять перемещаемые объекты, это озна чает, что сборщик мусора не может найти свободное место для размещения новых объектов, и попытка создания новых объек тов приведет к исключению Exception.

Сборщик мусора старается удерживать размер кучи нулевого уровня в пределах размера кэш-памяти второго уровня. При этом минимизируются издержки на обращение к памяти при наиболее частых сбора мусора. Анализируя работу своего ложения, полезно обратить внимание на то, позволяет ли оно сборщику мусора использовать данную оптимизацию.

Закрепленные объекты Как упоминалось ранее, закрепленными называют объекты, по меченные как возможно используемые потоками, Анализ производительности управляемого кода ми неуправляемый код. Во время работы сборщик мусора дол жен игнорировать такие объекты. Это необходимо по той при чине, что изменение адреса о время уплот нения или перемещения) обычно серьезные сбои в неуправляемом потоке. Поэтому до тех пор, пока объект являет ся закрепленным, сбор мусора его не затрагивает.

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

Некоторые объекты имеют ссылки не ресурсы, например сетевые или При уничтожении та кого объекта обычно теряется ссылка, поэтому разработчики могут предписать сборщику мусора, чтобы объект перед нием в обязательно порядке проводил очистку Ч завершение ization).

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

Во время сбора мусора ожидающие завершения объекты не уда ляются, а переходят в следующее поколение. Этот переход отсле живается счетчиком Survivors объекта Memory. Кроме этого, переход осуществляют и те объекты, на которые ссылаются завершенные объекты. Их переходы отсле живаются счетчиком Promoted CLR Memory.

При приложения важно избегать за грузки памяти объектами, прямо или косвенно подвергающими ся завершению.

194 Глава Сборщик мусора на серверах и рабочих станциях раз, когда происходит сбор мусора, сборщик мусора дол жен исполнение осуществляющих доступ к положение которых в будет изменяться при переходе в другое поколение и уплотнении. Выбор наилучшего режима работы сборщика мусора зависит от типа приложения.

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

Итак, для сборщика мусора Microsoft предлагает два режима ра боты. При этом заметьте: наилучший режим не выбирается ав томатически Ч задает режим Workstation CC до тех пор, пока разработчик не укажет, что необходимо исполь зовать режим Server GC (mscorsvr.dll).

Примечание По нашему опыту для большинства сценариев Web-приложении лучшую производитель ность показывает режим Server CC.

Период выполнения Ч исключения раз когда метод сталкивается с в ходе обычного исполнения ситуацией, он создает объект описывающий непредвиденное условие (например, нехватку па или отказ в доступе). В таком случае говорят, что поток пре дупреждает CLR о наличии сбоя и невозможности продолжить выполнение вплоть до устранения исключения.

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

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

в этом Анализ производительности управляемого кода случае говорят, что приложение продолжает для корректного завершения.) Предположим, что метод к методу кото в свою к методу а ге нерирует исключение Пока поток ищет соответствующий сгенерированному исключению фильтр, CLR его выполнение. Метод может обла дать обработчиком исключений с фильтром для ZeroException. Если исключение к этому фильтру не CLR продолжит поиск подходящего филь тра. Если ни один из фильтров, заданных функцией bar(), так и не подошел к исключению, то система направит стек вызовов к той функции, которая обратилась к В нашем случае это функция foo(). Теперь предположим, что обладает обработчи ком для Тогда этот об работчик будет и перехват исключения.

Говоря о перехвата depth), мы имеем в виду число которые CLR необходимо пройти по стеку для нахождения соответствующего обработчика исклю чений, В нашей гипотетической модели эта глубина равняется Если бы перехватила свое собственное исключение, глубина стала бы нулевой, А если бы потребовалось проде лать обратный до функции глубина рав нялась бы 2.

Как только исключение перехвачено, приложение возобновляет работу в блоке программы, носящем название заключительного блока. Цель заключительного Ч произвести очистку после всех операций, которые быть прерваны исключением.

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

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

196 Глава Исключения неуправляемого кода Когда неуправляемый код генерирует исключение, которое не может перехватить сам, оно преобразуется в.NET-исключение и CLR будет пытаться его устранить. Как и в случае других если CLR не сможет устранить исключение, то она остановит выполнение приложения.

Неуправляемые исключения, не затрагивающие CLR, не рируются никаким счетчиком производительности CLR Однако неуправляемого кода будут регистри счетчиками # of Thrown. При этом счетчик про изводительности to Catch Depth считает только стековые среды В результате чего отображаемая глубина перехвата меньшей реальной.

Исключения и исключений является ресурсоемким процессом. Ког да CLR просматривает стек вызовов в поиске надлежащего об работчика исключений, выполнение затрагиваемого потока при останавливается. А если обработчик найден, то он вместе с не которым количеством заключительных блоков должен иметь можность выполнить свою работу до нормального выполнения.

Предполагается, что исключения Ч события не частые. Также считается, что затраты на их пошаговое устранение окупают по лучаемый прирост производительности. При мониторинге харак теристик приложения возникает соблазн поиска наиболее ресур соемких Однако к чему настраивать приложение для ситуации, возникновение которой не предполагается? Приложе ние, которое быстро избавляется от исключений, реальной работы тратит усилия на борьбу с ними. Таким образом, мы рекомендуем вам идентифицировать те зоны, в которых наиболее часто возникают исключения, и дать им необ ходимое время для того, чтобы приложение смогло продолжить нормальное выполнение.

Счетчики производительности Теперь, после знакомства с факторами Framework, оказы вающими прямое влияние на производительность ния, мы проанализируем несколько счетчиков которые Анализ производительности управляемого кода оценивать производительность Framework и уп кода. Мы не будем рассматривать здесь суще ствующие счетчики, поскольку это потребовало бы куда больше места, чем объем этой главы. Мы познакомим вас с теми счет которые обладают оптимальным соотношением качество. По нашему мнению, эти счетчики в кратчайшее мя помогут собрать почти всю информацию о приложении.

Заметьте: этот подкласс счетчиков не отражает всех стей мониторинга производительности Web-приложения В зависимости от архитектуры системы вам, возможно, придется использовать другие счетчики и даже те, которые не име ют непосредственного отношения к Совет Если вы заинтересованы в чтобы сбор данных о производительности был включен в раз рабатываемую вами задействуйте про странство имен Counter.

Объект CLR Memory Все счетчики этого объекта показывают, каким образом framework использует память. от того, работаете ли вы с Web-приложением или с персональным приложением эти счетчики помогут вам оценить использование памяти системы. Однако они не отслеживают расход памяти неуправля емым кодом, даже в том случае если код частью анали зируемого Поэтому, когда приложение включает управляемый и неуправляемый код, полученные данные об ис пользовании памяти будут неполными.

Счетчик # GC Handles Счетчик # GC Handles отражает число описателей сборки мусо используемых данных момент. Это описатели управляемой среды и ресурсов, находящихся вне CLR. Единственный описа тель может занимать лишь небольшой памяти управляе мой кучи, однако представляемые им ресурсы вносят существенный вклад в снижение производительности приложения. Весьма вероятна высокая активность лей в случае создания множества объектов Web-приложением.

198 Глава Например, если сценарий отдельного требует на значения неуправляемого ресурса типа каждый раз при выполнении этого сценария пользователем содержащий массив создается вместе с соответствующим описателем GC. При большой особенно во время обращения к это му сценарию, Web-сайт создает большое количество GC обработчиков, что в некоторых случаях приводит к работе приложения.

Счетчик # Gen 0 Collections Этот и два следующих счетчика важны для оценки эффективно сти очистки памяти. Счетчик # Gen 0 Collections показывает, сколько выполнялся сбор мусора в нулевом поколении с на чала работы приложения. раз при сборе мусора исполь зуемые объекты нулевого поколения осуществляют переход в первое поколение. Как уже говорилось, единственным условием, при котором происходит переход из нулевого поколения, является необходимость создания в нем объекта, ко торого к памяти превышают имеющиеся. В этом случае исполь зуемый объект перейдет с уровня нулевого поколения и освобо дит ресурсы для создаваемого объекта. Интенсивность сборов в нулевом поколении обычно соответствует интенсивности, с приложением выделяется память.

Счетчик # Gen Collections Этот счетчик показывает, сколько раз производился сбор кучи первого поколения с начала работы приложения. Использовать его следует аналогично счетчику # Gen О Collections. Интенсив ный сбор мусора в первом поколении Ч признак нехватки ресур сов, выделенных для объектов, осуществляющих переход из ну левого поколения. В этом случае осуществляется переход объек тов во второе поколение, в результате чего тратится больше ре сурсов на том уровне.

Счетчик # Gen 2 Collections Этот счетчик регистрирует, сколько раз объекты второго поко ления подвергались сбору мусора с начала работы приложения.

Из трех счетчиков, анализирующих информацию о сборе мусо ра на уровне поколений, счетчик # Gen 2 считается наиболее важным. В случае его высокой активности при работе Анализ производительности управляемого кода с Web-приложениями может потребоваться перезапуск процес са Это когда ресурсы всю память второго поколения. Перезапуск приводит к выделению дополни тельной памяти.

Счетчик # Total Committed Bytes Этот счетчик регистрирует виртуальной памяти, занимае мой приложением. что в идеале приложение должно занимать по возможности меньшую память для снижения загруз ки сборщика мусора.

Счетчик % Time in GC Этот счетчик количество бремени, потраченное сбор щиком мусора на сбор и уплотнение памяти. Если приложение не оптимизировано, вы увидите, что сборщик мусора работает не прерывно, осуществляя перевод и удаление Счетчик Gen 0 heap size Счетчик сборщика мусора Gen 0 heap size показывает максималь ное количество байт, которое может выделено нулевому поколению. Сборщик мусора динамически регулирует объем па мяти первого поколения, изменяя его во время выполнения при ложения. Уменьшенный размер кучи свидетельствует об эконо мии памяти и, таким образом, позволяет GC снизить размер ра бочего набора приложения.

Счетчик Gen 0 Promoted Bytes/sec Этот счетчик показывает количество байт, перемещаемых в се кунду из нулевого поколения в первое. Приложение может рабо тать с большим числом переходов, однако, если переход осуще ствляют объекты небольшого размера, вы не увидите высокой активности этого счетчика. Поэтому его следует использовать вместе со счетчиком # 1 heap size, чтобы узнать, являются ли переходы следствием плохого распределения ресурсов на пер вом уровне.

Счетчик Gen 1 heap size Этот счетчик показывает текущее число байт первого поколения, В отличие от Gen 0 heap size он не выводит максимальный раз мер первого поколения, а текущий объем памяти, 200 Глава выделенный его объектов. При работе с этим счетчиком одновременно потребуется счетчик # 0 С увели чением количества сборов в нулевом поколении обнаружите одновременный рост объема кучи первого поколения. В конеч ном счете назреет необходимость перемещения объектов во вто рое что приведет к неэффективному использованию памяти.

Счетчик Gen 1 Promoted Bytes/sec Счетчик 1 Promoted Bytes/sec показывает Ч какое количе ство в секунду осуществляет переход из поколения 1 в по коление 2. Как и в случае с Gen 0 Promoted вам следу ет использовать Gen 1 Promoted вместе со счетчиком Gen 2 heap size. Вместе они дадут вам исчерпывающую инфор мацию о количестве для перемещаемых во второе поколение объектов памяти.

Счетчик Gen 2 heap size Этот счетчик показывает текущее число байт во втором поколе нии. При мониторинге приложения с большим количеством пе реходов во второе поколение будет наблюдаться увеличение раз мера кучи, поскольку здесь объекты нельзя пере местить далее.

Объект CLR Loading Описанные в разделе счетчики объекта CLR Loading при совместном использовании с другими счетчиками типа % Proces sor Time (% загруженности предоставят вам подроб ную информацию о влиянии, которое оказывает на системные ресурсы загрузка.NET-приложений, доменов приложений, клас сов и сборок.

Счетчик Total AppDomains Этот счетчик показывает максимальное число доменов ний (AppDomains), загруженных с момента запуска приложения.

Как было сказано ранее, домены приложения Ч безопасное и универсальное средство обработки данных, которое используется для обеспечения изолированной работы приложений в од ном том же процессе. Для Web-приложений иногда необходи использовать множество приложений внутри процесса Анализ управляемого кода С точки зрения производительности знание числа вы полняющихся G данный момент приложений является критическим, так как каждый раз, когда вы создаете или удаляе те домен приложения, системные ресурсы испытывают дополни тельную нагрузку. Также важно знать о взаимодействии между доменами приложений. если ваши приложения во время выполнения должны выходить за домена, то бу дут иметь место контекстные переключения. Как вы уже знаете из главы 4, они ресурсоемкими. Особенно это замет но, если на сервере происходит более 15 000 контекстных пере ключений в секунду.

Счетчик Total Assemblies Этот счетчик показывает общее количество сборок, загруженных с начала работы приложения. Сборки могут загружены как когда их код совместно используется все ми доменами приложения, или как когда их код предназначен для конкретного домена. Если сборка загружена как прирост активности ка будет однократный. Вам следует знать об общем количестве сборок загруженных на сервере из-за ресурсов, которые необ ходимы для их создания и уничтожения. Иногда разработчики загружают сборки, которые на самом деле не обязатель ными для приложения.

Счетчик Total>

Объект CLR LocksAndThreads При поиске лузких мест, относящихся к потокам или процессам, лучше всего начать с CLR Здесь мы обсудим те счетчики объекта CLR ко торые позволяют быстро и эффективно устранить возможный конфликт.

202 Глава Счетчик Contention Rate/sec Этот счетчик сколько раз з секунду во время выпол нения поток делает неудачные попытки запроса управляемой блокировки. Следует отметить, что в случае тяжелого конфлик та потоки не обязательно получают блокировки в запрашиваемом ими порядке.

Счетчик Total # of Contentions Этот счетчик показывает общее число неудачных попыток за проса блокировки, сделанных потоком в CLR.

Счетчик Current Queue Length Этот счетчик общее число потоков, ожидающих в данный момент управляемые блокировки. Если вы видите, что при постоянной загрузке приложения показания счетчика непре рывно увеличиваются, то, возможно, имеет место неразрешимая Различие между неразрешимой и разрешимой бло кировкой заключается в том, что неразрешимая блокировка воз никает, когда ошибка в логике кода делает можным снятие блокировки с объекта.

Объект CLR Exceptions Производительность приложений, которые генерируют очень много исключений, может быть очень низкой. В идеале приложе ние не должно генерировать исключений вообще. Однако часто разработчики намеренно включают генерацию исключений как часть проверки ошибок. До запуска производства при ложения код, генерирующий исключение, необходимо уда лить. Здесь мы показали два счетчика объекта CLR Excep tions. Если вы решите использовать один из них, тогда со ветуем выбрать Exceps Thrown/sec. Если его показания превысят исключений в секунду, это можно считать веским основани ем для проведения дополнительного исследования кода прило жения.

Счетчик # of Exceps Thrown Этот счетчик показывает общее число исключений, сгенериро ванных после запуска приложения. Он регистрирует как так и неуправляемые исключения, преобразованные Анализ производительности управляемого кода з (например, исключение из-за ссылки на несу указатель в коде повторно генери в управляемом коде как исключение Однако он не регистрирует исключения, сге и перехваченные в неуправляемом коде. Этот счетчик учитывает как обработанные, так и необработанные ис а также те, что генерируются повторно.

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

Счетчик # of Exceps Thrown /sec Этот счетчик показывает количество исключений, генерируемых в секунду. Он регистрирует как так и неуправ ляемые исключения, преобразованные в одна ко не регистрирует исключения, сгенерированные и перехвачен ные в неуправляемом коде. Кроме этого, он учитывает как обра ботанные, так и необработанные исключения. Как уже говори лось, если вы заметили, что число исключений в секунду составляет 100 и более, то вам необходимо проанализировать исходный код длл определения причины и места, где генериру ются эти исключения.

Объект CLR Security В зависимости от сколько внимания вы уделяете ности Web-приложения, вы будете либо очень активно пользо ваться предлагаемым в этом разделе набором счетчиков, либо не пользоваться им вообще. Эти счетчики необходимо применять лишь в том случае, когда это нужно. Несмотря на то, что проверка безопасности снижает производительность при ложения, проводить ее необходимо. Однако неправильное ис пользование средств безопасности Framework не только создает бреши в безопасности, но и снижает производительность приложения.

204 Глава Счетчик # Link Time Checks Работая с этим счетчиком, вы часто будете наблюдать его повы шенную активность. Это может ввести в заблуждение, не чем она вызвана. Впрочем, это справедливо и других счетчиков. Отображаемые показания не указывают на зна чительное ухудшение производительности, а свидетельству ют об активности системы безопасности. Счетчик показывает, сколько всего после запуска приложения выполнено проверок защиты по правам доступа кода (Code Access CAS) в период в период связывания осуществ ляется один раз для каждого вызывающего и на одном уровне и, таким образом, она менее ресурсоемка, чем проход по стеку.

Счетчик % Time in RT checks Этот счетчик показывает, сколько времени в процентах затраче но на проверку CAS в период после последней ана проверки. Счетчик обновляется в конце проверки и показывает не среднее, а последнее зарегистрированное значе ние. Если значение этого счетчика большое, то вам необходимо проанализировать Ч что проверялось и как часто.

может излишняя глубина обхода стека (счетчик Stack Walk Depth будет обсуждаться далее) или многочисленные проверки в период связывания.

Счетчик Stack Walk Depth Этот счетчик показывает глубину стека во время последней про CAS в период Такая проверка осуществляет ся посредством прохода по стеку. Это, например, происходит, когда приложение обращается к у которого четыре ме тода (А Ч D). Если код обращается к методу А, глубина прохода по стеку равна Однако если бы вы обратились к методу D, который в свою очередь обращается к методам С, В и А, глубина обхода стека оказалась бы равной 4.

Счетчик Total Runtime Checks Этот счетчик показывает общее число проверок CAS в период выполнения после запуска приложения. Проверки CAS в период выполнения происходят при обращении вызывающего Анализ производительности управляемого кода с запросом о конкретном разрешении. Во время проверки сматривается стек потока программы.

Используя данные этого счетчика и счетчика Stack получите исчерпывающее представление о потерях произ водительности во время проведения проверки безопасности.

Большое количество общего числа проверок в период выпол нения и большая глубина стека свидетельствуют о потере про изводительности.

Профилирование управляемого кода В этом разделе речь пойдет о как профилировать управляе мый неуправляемый) код с помощью DevPartner Studio 7. от Compuware. Сейчас представлено довольно много профили ровщиков, но здесь в качестве примера мы DevPartner Studio, командой АСЕ.

Знакомство с Compuware DevPartner Studio DevPartner Studio Professional Edition от Compuware Corporation поможет вам создавать надежные и высокопроизводительные приложения. Анализ производительности облегчит поиск и точ ную локализацию критических элементов в коде, сторонних ком понентах или операционной системе даже в случае отсутствия исходного кода. Пробную версию DevPartner Studio 7.0 Professio nal Edition можно получить на devpartner/.

Профилирование с помощью DevPartner Studio Во многих приложениях за производительность в большой сте пени лишь относительно небольшая часть кода.

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

Во время анализа рабочих характеристик DevPartner Studio изме ряет частоту и время выполнения кода вплоть до отдельной стро ки применительно к широкому ряду компонентов: Visual Basic, 206 Глава C + +, Visual Basic Visual C, C/C+ + а также Web приложениям с и VBScript и при использовании IE или IIS.

Сбор данных о производительности при помощи DevPartner Studio не затруднений. В случае управляемого кода просто запустите приложение, активировав Performance В случае неуправляемого кода активируйте Instrumentation Manager и приложение.

Один из возможных способов Ч первоначально собрать харак теристики на уровне метода (а не чтобы выявить наибо лее ресурсоемкие методы. Далее следует собрать данные уже на уровне строки. Так вы быстро выявитье группы методов, претен дующие на улучшение в первую очередь.

Примечание Чтобы не собирать данные для всех системных проверьте переключатель Exclu de System Images в окне DevPartner Performance and Coverage Exclude Images. После исход ного кода установите этот таким об разом, чтобы активировать изучение использования приложением системного кода. Это особенно важ но в случае использования Framework.

Окно Session По окончании выполнения приложения характеристики дительности выводятся в окне Session, как это показано на рис. В панели перечислены исходные файлы и ные образы, используемые во время сессии, а также процент зат раченного в период выполнения времени на каждый Вы можете быстро просмотреть любой а также содержащие ся в нем методы. Имейте в виду, что в данном примере мы ис пользуем приложение со смесью родного C + + и С# кода. Кро ме того, вы можете отобрать группы полезных файлов или ме (например, 20 наиболее используемых методов), чтобы сконцентрировать внимание на коде, который используется боль шую часть времени выполнения приложения или обращения к которому наиболее часты. Справа расположена панель данных, Анализ производительности управляемого кода на перечислены методы и их исходный код, а также ито говая - (Drivel) E Х j ! j Top Source Methods 0. 0, г 0.4 11.0 [..

Called Methods 0.1 60.2 L 1. 0.0 0.7 ( 0.0 0. 0. o.o [ 0.0 3 0.0 0.0 0,0 0 С 0.0 0,0 С P P Рис. 7-1. Окно Session DevPartner Studio :

;

- - - ft Х 14 { 73 213 1.4 ! 112 НИНЕ - ICC ;

73 213 : Э.ЭЭ 241.1 hDC - ;

73 213 E 1.0 82 0, 1, ;

78 2. 0. 165 78 1.7 Select (hDC, 6.0 485 092.9 (hDC, 1.1 ;

353. 218 ! 18 > J Рис. 7-2. Окно Source Code DevPartner Studio Один из работы Ч сортировка сессионных данных по среднему времени, которое на каждый метод, с последующим анализом на предмет улучшения наиболее ресур соемких методов. Выбрав на панели данных окна Session метод, вы сможете подробно изучить исходный код. На рис. 7-2 пока Глава зан пример исходного кода, аннотирован числом каждой строки процентом времени, затраченного на вызываемые (дочерние) функции, и общим количеством време ни, затраченным на выполнение строки кода. Кроме того, выде наиболее ресурсоемкая строка, которая может служить лот для изменений в выбранном коде.

Окно Method Details Другой способ повысить производительность Ч исследовать взаимоотношения между функциями, к которым происходит об ращение в приложении. Как и прежде, сначала необходимо вы брать метод. Описание метода включает методы, к которым он обращается, и методы, которые обращаются к нему (рис. 7-3). В верхнем разделе окна идентифицируется выбранный метод и указаны характеристики его производительности. В разделе Parents перечисляются все методы, которые к нему обращаются, а в разделе Children Ч все методы, к которым обращается он сам.

Режим просмотра Method Details позволит вам разобраться во взаимоотношениях метода и происходящих при этом затратах, а просмотрев последовательность вы лучше работу кода и влияние вызовов на инфраструктуру.

Рис. 7-3. Окно Method Details DevPartner Studio Анализ производительности управляемого кода Работа с распределенными приложениями Studio генерирует отчет о рабочих характеристиках распределенных приложений, включая приложения, работающие з Web. Программа позволяет осуществлять комплексное профи лирование распределенных приложений с компонентной струк турой. В случае DevPartner осуществляет сбор данных о приложениях, созданных в Visual Studio а также об использующих языки сценариев, поддерживаемые IE и Во время работы приложения DevPartner может получать информацию о каждом отдельном локальном или уда ленном процессе, включая сессионные данные на сервере и со поставлять эти данные. При сопоставлении данные о разных процессах объединяются в один DevPartner автоматичес ки сопоставляет сессионные данные с различными процессами, а именно:

Х с обращениями на основе протокола DCOM между метода ми в различных процессах;

Х с HTTP-запросами, о которых в качестве клиента IE, а в качестве сервера Ч I IS.

Чтобы сохранить между методами объектов а так же связь между клиентом HTTP и сервером (IE и IIS), DevPartner автоматически сопоставляет полученные из этих данные.

Затем он объединяет сопоставленные данные с данными клиен та в один сессионный В режиме просмотра Method Details вы можете просмотреть этот файл и методы. В том случае если связи на основе протокола СОМ или связи клиент/сервер между и MS не стоит использовать команду Correlate Performance Files, выбрав Tools в меню DevPartner, чтобы объе динить данные различных сессий вручную.

Эффективный анализ производительности Framework очень сложна и богата возможностями. В ней удается достичь много, используя лишь несколько строк кода. Это удобно разработчикам, однако создает трудности при ке производительности приложения. Например, вы можете об наружить, что 95% времени выполнения приложения занимает 210 Глава Framework. Как повысить в этом случае?

В следующих разделах описаны основные принципы повышения продуктивности анализа с помощью DevPartner Studio.

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

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

odd начальные затраты Framework осуществляет много единовременных инициали заций. Чтобы это не искажало результаты, тестируйте приложе ние, профилируя все функции, а затем, с помощью кнопки Clear на панели инструментов удалите данные. После запустите тест, те же функции получения бо лее точной картины о производительности.

Учитывайте затраты Framework Используйте счетчик % with на вкладке Method List или Source, чтобы узнать, как много времени тратит Framework.

С помощью окна Child Methods вкладки Method Details проверь те Framework, чтобы выяснить, какие методы являются ре сурсоемкими и почему, Переработайте приложение таким обра зом, чтобы число выполняемых им стало меньше, или не так часто обращайтесь к Framework.

Осуществите полный сбор данных о распределенных приложениях При анализе производительности Web-приложения, невых клиент-серверных или приложений, исполь зующих Web-сервисы, включите в тест все компоненты удален Анализ производительности управляемого кода приложений. Применяйте DevPartner Performance и Coverage Remote Agent для настройки сбора данных о производительнос ти на удаленных системах. Если ваше приложение использует компоненты тогда перед сбором данных эти компоненты для анализа производительности. Конечно, рекомен дации, касающиеся представлений о работе приложения, стар товых затрат и затрат равно применимы к сбо ру данных о серверных компонентах, Использование AppMetrics для за компонентами Enterprise Services СОМ+ предоставляет код) для создания масштабируемых и эффективных Через Enterprise Services эти компоненты также доступны управ ляемому коду Framework. К их функциям относится коорди нация транзакций для распределенных ресурсов, управление пу лом объектов, защита на основе ролей и т. д. Вы можете настро ить компоненты управляемого и неуправляемого кода на исполь зование этих AppMetrics for Transactions (AppMetrics) Ч это система мониторин га приложений Enterprise Services, она при профи лировании производительности приложений, активно использу ющих Многим приложениям, с которыми мы имеем для с существующими системами, приходится лобертывать свой управляемый код в компоненты СОМ +. По лучаемые с помощью AppMetrics характеристики позволяют быст ро определить, снижает ли приложение СОМ+ производительность.

AppMetrics годится для мониторинга управляемых и неуправляе мых компонентов Enterprise Services. Она разработана для наблю дения за приложениями, работающими как в опытных, так и се рийных средах.

AppMetrics Manager Для снижения влияния мониторинга на производительность си стемы и приложения в AppMetrics используется схема лагент диспетчер. Агент располагается на сервере приложения, занимая минимальное количество системных ресурсов, собира ет данные о компонентах Enterprise Services. подход позво 212 Глава ляет AppMetrics получать более точные данные о приложениях независимо от того, работают они на самом деле или их работа имитируется.

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

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

Настройка агента и диспетчера AppMetrics Для оценки с управляемым и неуправляемым кодом при работе nog Enterprise Services выполните следующие действия.

1. На компьютер с AppMetrics Manager установите монитор Manager.

Рис. 7-4. Панель настройки Diagnostics Application Анализ производительности управляемого кода 2. Добавьте монитор Agent к монитору Manager, чтобы создать монитор Agent на сервере приложения.

3. Выберите для мониторинга на сервере.

4. Вы можете настроить мониторинг конкретных компонентов приложений.

Использование для предварительного мониторинга Для предварительного мониторинга AppMetrics предусмотрен Diagnostics Monitor, который регистрирует данные отдельного компонента и активность работающего при ложения.

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

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

С помощью такого анализа удается определить, находиться ли лузкое место в корневого компонента или где-то на бо лее низком уровне обращений метода з подчиненном компоненте.

На рис. 7-5 показан фрагмент отчета AppMetrics for Transactions, Х логическую цепь метода;

Х компонент который запускает экземпляр подчиненного компонента Х метод активированный на подчиненном компоненте;

214 Глава Х систему именования межпрограммных вызовов (cross calls). Перед такими вызовами стоит имя другого приложения с двоеточием. В данном примере компонент находится в другом приложении.

Рис. 7-5. отчет Примечание Кроме здесь информа в отчете для всех приводятся вре мя время работы и коды ошибок.

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

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

Сделать это можно несколькими способами. Например, переме стить подчиненный компонент в приложение, содержащее пер компонент или же переместить подчиненный компонент в библиотечное приложение.

Дополнительная диагностика Прежде чем запустить приложение в следует получить представление о его возможностях. На рис. 7- показан фрагмент отчета в котором подробно опи сываются активность метода на экземплярах компонента FMSto в течение 10 минут работы.

Заметьте, что средняя продолжительность проверяемого метода довольно большая и не все обращения заканчивались успешно.

Анализ производительности управляемого кода Рис. 7-6. Отчет о методах Наблюдение за тем, как в течение времени меняется тельность довольно полезно. На рис. 7-7 показан фрагмент отчета AppMetrics for Transactions, отражающего актив ность компонента в течение 4-часового периода работы.

Рис. 7-7. Отчет о компонентах Мониторинг рабочего приложения Для мониторинга приложений Enterprise Services в рабочей де AppMetrics предлагает Production Monitor, который через оп ределенные промежутки времени создает метрики активности приложений Enterprise Services. Он менее к ресур сам и менее информативен, чем Diagnostics Monitor. Production Monitor вычисляет итоги и степень активности компонентов и их как показано на рисунках 7-8, 7-9 и Рис. 7-8. Активные компоненты 216 Глава (Started.

Рис. 7-9. Частота применения компонентов Рис. 7-10. Длительность работы компонентов Кроме этого, Production Monitor создает такие метрики, как за пуск, и сбои приложения. интерфейс AppMetrics отображает метрики для каждого процесса ния Enterprise Services. На следующем рисунке показано исполь зование ресурсов процессом, соответствующим Production Monitor также предлагает мониторинг по предупреж дению. Вы можете указать границы активности определенной метрики компонента, например продолжительности. Если AppMetrics обнаружит, что в системе выше указанного уровня, то он отправит предупреждение по электрон Анализ производительности управляемого кода ной почте или SNMP. Кроме того, среагирует на пре дупреждение запуском специального компонента СОМ, в кото ром вы можете запрограммировать автоматическую реакцию на данное состояние системы.

Рис. 7-11. Окно Application Process Runtime j Dot Рис. 7-12. Окно Components Process 218 Глава выдает метрики для каждого отслеживаемого нента Enterprise Services. На рис. что работа компонента в среднем занимает более 10 секунд от момента создания до завершения. Так как такие параметры выходят за указанные рамки, будет выдано предупреждение.

Заключение Знание о профилировании и интерпретации рабочих характери стик управляемого кода Ч ключ к построению расширяемого и устойчивого Web-приложения Профилирование управляе мого кода можно используя System Monitor и счет чики производительности Полученная информация дится вам при работе с любыми средствами оптимизации кода.

Подробнее о масштабируемом, высокопроизводительном коде рассказано в Writing Scalable Code Саймона (Simon и Майка Паркса Parks), которая должна выйти в Microsoft Press в время.

Глава В любом приложении важнейшими операциями считаются полу чение, сохранение и отображение данных..NET-приложения не исключение, и потому анализ и SQL-уров ня абсолютно необходимы для реализации масштабиру емости. Покупка дополнительного или более мощного оборудо вания для лузкие места на SQL-уровне, обычно не решает проблемы. Прежде чем покупать обо рудование, необходимо выявить лузкие места, влияющие на масштабируемость. Например, они могут проявляться в увеличения операций ввода-вывода или слишком высо кой загрузке процессора неверно выбранных индексов или плохо написанных запросов.

Эта глава выявлению лузких мест на SQL-уровне. Мы обсудим ряд связанных с индексами типичных проблем, выявлен ных группой Ч группой анализа производительности ком пании Microsoft Ч в процессе работы. Естественно, пойдет не обо всех возможных проблемах производительности на SQL уровне Ч их не удастся вместить в рамки одной главы. Однако мы надеемся, что приведенная здесь информация об используе мых нами методах выявления лузких мест, позволит вам само стоятельно исправить их или корректно описать, если вы реши те обратиться за помощью к специалистам. Для демонстрации мы используем примеры на основе сайта где при необходи специально создаем проблемы. Результаты примеров главы получены с использованием двухпроцессорного сервера на базе Pentium с 1 памяти, на котором был установлены Microsoft SQL Server 2000 Enterprise Edition с Service Pack 2 и Windows 2000 Advanced Server с Service Pack 2.

220 Глава Чтобы устранить проблемы производительности и масштабиру емости, прежде необходимо изучить структуру базы данных при Если вы используете SQL Server 2000, вам также необ ходимо хорошо знать Transact-SQL внутреннее устрой ство SQL Server, например как оптимизатор запросов выбирает план исполнения;

как хранятся индексы и данные и как SQL Server использует кэширование данных и планов исполнения. Мы пред полагаем, что вы уже работали с SQL Server 2000 в определен степени знакомы с его встроенными инструментами, таки ми, как SQL Query Analyzer и SQL Profiler. Если же это не так, то рекомендуем обратиться к следующим источникам:

Х SQL Server Books Online (устанавливается вместе с SQL Server 2000);

Х Delaney Inside Microsoft SQL Server 2000 Press, 2000);

Х Ken Henderson The Guru's Guide to Transact-SQL (Addison 2000);

Х Microsoft SQL 2000 Performance Tuning rence (Microsoft Press, 2001).

Кроме того, вы должны уметь создавать на сервере базы данных эксплуатационные или предполагаемые уровни нагрузки. Часто нагрузки, одним пользователем, недостаточно для чтобы проблемы масштабируемости на SQL уровне. Здесь зам может понадобиться из главы в которой мы рассказывали о Microsoft Application Center Test, как инструменте тестирования. Надлежащие сценарии нагрузочного тестирования, моделирующие в тестовой среде реальные эксплуатационные нагрузки, вам выявить луз кие места, прежде чем они возникнут во эксплуатации приложения. Если вы определили, что для решения проблемы требуется изменение индекса или запроса, то сможете вать тестовую среду для проверки своих предположений, преж де чем вносить изменения в работающее приложение.

лузких мест Во многих случаях определить наличие лузких мест на SQL-уров не очень просто. Например, если к одному серверу базы данных Анализ SQL-уровня обращается несколько Web-серверов, то уменьшение числа пос ледних должно снизить пропускную способность приложения.

Если же пропускная способность не снижается при уменьшении числа Web-серверов, вероятно, лузкое место находится на SQL-уровне.

лузкие места на тестовых клиентских компьютерах возникают до как со здана достаточная нагрузка на Web-серверы или SQL-серверы. Таким образом, во время каждого теста необходимо периодически проверять степень загрузки ресурсов клиентских компьютеров.

Чтобы выявить проблему на SQL-уровне, достаточно уменьшить число как описано выше, или понаблюдать за за грузкой процессора на каждом из уровней А вот оп ределить причину проблемы и предложить ее решение весьма сложно: прочитав эту главу, вы не приобретете необходимые навыки мгновенно. Мы вас с тем, как мы лузкие места на SQL-уровне, однако учиться на собственном опыте. Начнем мы с обсуждения инструментов, поставляемых вместе с SQL Server 2000.

Наш инструментарий Для решения большинства проблем, с SQL, мы исполь зуем только входящие в поставку SQL Server 2000.

Неэффективные запросы удается выявить с помощью SQL Profiler, блокировки Ч средствами SQL Profiler и SQL Query Analyzer;

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

SQL Profiler При установке по умолчанию SQL Profiler доступен из меню Пуск, раздел SQL Server\Profiler.

ПРИМЕЧАНИЕ Для запуска трассировки пользо ватель должен иметь административные права на соответствующем SQL-сервере.

222 Глава SQL Profiler, выберите нужный сервер и инфор мацию для входа в систему. После установления сессии откро ется диалоговое окно трассировки. В нем имеется 4 вкладки Ч General, Events, Data Columns u Filters, используемые для настройки параметров трассировки, На вкладке General задают название трассировки, шаблон трас сировки, а также режим сохранения данных в трассиров ки или в SQL-таблице. В случае сохранения результатов в файле необходимо указать каталог имя файла, при сохранении дан ных в таблице слдеует сервер, базу данных и таблицу.

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

Обычно мы задаем мониторинг следующих событий:

Х Stored Procedures:

и Эти события генерируются по обра ботки оператора, хранимой процедуры, RPC или пакета (batch вывод в трассировочную информацию столбцов тек чтения, нагрузки процессора и длительности, вы выявите долго код в терминах ресурсов про цессора. Информация о требуемых операциях чтения вам пригодится: именно с будете сравнивать результаты оптимизации;

Х Stored Procedures: u TSQL:

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

Х Sessions: Existing Connection Данное событие позволяет проверить фактические значения параметров SQL Server для сессии базы данных. Параметры сессии могут влиять на об Анализ SQL-уровня работку запросов. Например, для использования индексиро ванных представлений (view) необходимо установить в ON параметр иначе для выборки данных будет нижележащая а не кластерный ин декс для представления;

Х Stored Procedures: Исполнение цедуры подразумевает компиляцию и Каждый из этих этапов требует определенного времени. В идеале разбор и компиляцию кода следует выполнять одно чтобы затем ресурсы сервера расходовались только на Неправильно написанная хранимая процеду ра может требовать перекомпиляции при каждом вызове, что отрицательно влияет на время ее исполнения и даже вызы вает блокировки. С помощью данного события удается опре делить масштаб перекомпиляции и выявить код, требующий оптимизации, включив в ту же трассировку событие SP:

Starting;

Х Lock: Timeout and Lock: Deadlock Мониторинг данного со бытия необходим, так как оно напрямую влияет на масшта бируемость приложения. блокировки или дедлок вы зывают транзакции и ошибки на клиентской стороне;

Х Errors and Warnings: Attention Данное событие генерируется всякий раз, когда сессия завершается по клиента или по тайм-ауту. Для приложений, которым обычно требует ся длительное время на обработку, вам, вероятно, придется увеличить длительность тайм-аута или уменьшить число аутов. Например, в установить свойство в значение более 30 секунд (по умолчанию) для за просов, работающих долгое время;

Х Errors and Warnings: Missing Statistics SQL Sewer автоматически создавать и поддерживать статистику для таблиц и индексов. Эта представляет распределение значений в некоторых колонках таблиц и ин дексов и используется при обработке запросов для пла на выполнения. Если статистика отсутствует или устарела, то мо жет выбран неэффективный план исполнения, что отри цательно скажется на общей производительности приложения;

224 Глава Х Errors and Warnings: Join Predicate Данное событие генерируется раз, когда в запросе декар тово произведение (соединение без указания Декар тово произведение используются редко может ока заться результатом ошибки разработчика. Мониторинг этого события позволит определить, не используется ли данный тип соединения таблиц;

Х Errors and Warnings: Exception u Error Эти события по лезны для любых необычных щих в результата нагрузочного тестирования приложения. Мо ниторинг этих событий позволяет определить, являются ли они результатами повышенной нагрузки. Например, если устано вить для всех сессий флаги трассировки 1204 и 3605, то SQL Profiler зафиксирует информацию, связанную с дедлоками.

собой серьезную проблему, формиру ющую у пользователя плохое впечатление о приложении и чительно влияющие на пропускную способность приложения.

Подробнее о event Ч в SQL Server Books На закладке Data Columns можно указать столбцы, значения ко торых должны фиксироваться во время трассировки. Из 43 стол обязательными являются Event u SPID. В зависимости от интенсивности взаимодействия приложения с SQL-сервером и количества пользователей вы можете получить огромный мас сив трассировочных данных. что не все столбцы содер жат значения, так как зависимости от конкретного события некоторые столбцы не имеют смысла. Например, длительность имеет смысл только для событий завершения, таких, а для этот столбец останется пустым. Некото рые используемые нами столбцы, перечислены табл.

8-1. Часто используемые столбцы трассировки Столбец Описание Event события. Например, начало работы храни мой процедуры, установление сессии и т. д.

Text Текст SQL-команды. Столбец может быть пуст, если неприменима к данному событию CPU Использованное время процессора в миллисекундах см. след. стр.

Анализ SQL-уровня 8-1.

Столбец Описание Reads Число логических операций для исполнения запроса Writes Число физических операций записи, выполняемых SQL-командой Duration Длительность например исполнения хранимой процедуры StartTime начала события EndTime Время завершения Применимо к событиям, связанным с завершением операций NestLevel Глубина операции. если одна хранимая процедура вызывает другую, то глубина процедуры равна а вы зываемой 2. Соответствует значению переменной Application Name Название приложения, установившего сессию с сер вером HostName Название компьютера, на котором исполняется при ложение, выдавшее команду SQL запись пользователя Windows, в контексте которой исполняется клиентское приложение Либо имя Windows, либо регистрацион ное имя SQL Server Ч в зависимости от применяемо го аутентификации Подробнее о data columns Ч в SQL Server Books Online.

На вкладке задаются фильтры для ограничения результатов трассировки. Например, если вас интересует опре деленное приложение, то можно задать фильтрование по его имени. События, генерируемые SQL Profiler, исключаются по умолчанию. Чтобы познакомиться со доступными фильт рами, изучите вкладку Filters в диалоговом окне Trace Properties.

При выборе фильтра внизу вкладки появляется его описание, Теперь, когда вы познакомились с тем, какие виды информации можно собрать, поговорим о том, как анализировать результаты трассировки. SQL Profiler позволяет сохранять результаты трас сировки либо в файле, либо в На самом деле если вы решите сохранить данные в то за вами сохраняется 226 Глава право открыть его в любой момент и сохранить содержимое в SQL-таблице. Выбор за вами и от ваших предпочтений.

СОВЕТ Вы также можете выполнять запросы не посредственно по содержимому трассиров ки с помощью системной функции следующий запрос тия длительностью более миллисекунд из ла trace.trc в табличном формате:

SELECT FROM default) WHERE Duration > Подробнее о SQL Server Books Online.

По нашему опыту, для анализа больших трассировоч ных данных следует их в таблице и затем запросы к для информации, как пер вые N хранимых процедур, имеющих наибольшую длительность или средняя длительность исполнения вызовов хранимой Чтобы иметь возможность решать, медленно или нормально исполняется код, необходимо опреде лить критерии понятия медленно запрос.

СОВЕТ Мы рассматриваем любой код, который в условиях минимальной на приложение ис полняется в течение секунды или дольше как пред мет для дальнейших и возможных улучшений. Выбор данного критерия основан на что при нагрузке длительность исполнения такого кода возрастет, в результате чего уменьшается пускная способность приложения.

Выполнив трассировку несколько вы заметите, что всегда выбираете определенные и фильтры. В SQL Profiler пре дусмотрено средство, облегчающее задание часто используемых параметров трассировки Ч шаблоны, содержащие значения та ких Это позволит вам не задавать параметры для трассировки Создать шаблон очень про сто: выберите из меню File пункт Choose New Trace Template, no Анализ SQL-уровня которому отображается окно Trace где вы можете выбрать события, столбцы и фильтры. Затем на General щелкните Save As. Пункт Open Trace Template меню File позволяет открыть сохраненный ранее шаблон. Затем его мож но изменить и сохранить под другим именем, System Monitor Server поддерживает ряд объектов производительности для System Monitor. подробно рассматривался в главе где говорится о счетчиках, связанных с общесистемными ресур сами, такими, как процессор, диск сеть. В главе пойдет только о наиболее часто используемых нами чиках, характерных SQL Server. Другие счетчики подробно описаны в источниках, перечисленных в начале главы. В зависи мости от обстоятельств вам могут потребоваться и эти счетчи ки. Мы наиболее часто используем следующие счетчики произ водительности SQL Server:

Х Manager о Buffer cache hit ratio Процент страниц, которые были найдены в буферном пуле и которые не пришлось вать с диска (выполнять ввод-вывод). Малые могут свидетельствовать о недостатке памяти или плохих индексах;

* Statistics Object о User Connections Число активных SQL-сессий. Этот формационный счетчик в отчете показывает уровень па раллелизма в системе;

SQLServer:Locks о Lock Requests/sec Количество запросов на блокировку в секунду. Оптимизация запросов для снижения числа опе раций чтения в некоторых случаях уменьшает значение данного счетчика;

о Lock Timeouts/sec Число запросов на блокировку, завер шившихся тайм-аутом в процессе ожидания предоставле ния блокировки. В идеале значение счетчика должно быть равно 0;

228 о Lock Waits/sec Число запросов на блокировку, которые не были немедленно, В идеале значение счет чика должно максимально близким к 0;

о Number of Число запросов, дедлок. Дедлоки снижают степень масштабируемости при ложения и создают дискомфорт для пользователя. Значе ние счетчика должно равно 0.

Выполнив мониторинг экземпляров этих вы определите используемые типы блокировок и их вклад в общее значение счетчиков. Задав индексы и, по блокировке (lock hint), вы уменьши те проблем, связанных с блокировками.

Х Manager о Memory Grants Pending Число процессов, памяти рабочего пространства Значение счетчика должно максимально близким к О, если это не возникло лузкое связан ное с памяти;

Х Statistics о Batch Requests/sec Число пакетных запросов к секунду, показывает нагрузку на систему;

о SQL Число компиляций в секунду. В але значение счетчика должно мало. Близость этого счетчика и счетчика Batch requests/sec означает большое число произвольных fad-hoc) SQL-запросов;

о SQL Число в секун ду. Значение этого счетчика также должно быть мало. В идеале хранимые процедуры должны компилироваться од нократно с последующим многократным использованием полученных планов исполнения. Большое значение этого счетчика свидетельствует о необходимости кода хранимых процедур с целью минимизации перекомпиляции.

SQL Query Analyzer SQL Query Analyzer применяют в различных целях, например для исполнения при установке нового кода, для под счета числа вставляемых или обновляемых строк, для анализа Анализ SQL-уровня планов запросов или для исполнения различных сис темных хранимых процедур. Среди всех поставляемых з составе SQL Server 2000, Query Analyzer несомненно является инструментом наиболее часто используемым нашей Вместо подробного описания Query Analyzer мы продемонстри руем конкретные приемы его применения для анализа блокиро вок и планов исполнения далее в этой главе.

строк Пру исследовании сценариев, выполняющих вставку.

в таблицы, подсчет строк до и после нагрузочного полезен определений пропускной способности, для большой таблицы эта операция много Проще всего число строк в таблице посредством запроса к системной таблице SELECT о i on WHERE BY Обращение к меньше по сравнению со большой тысячи или миллионы строк. Следовательно,, чем больше число строк, тем более выгоден запрос Обратите что обычно ' к таблицам не следует использовать только когда подсчета строк в Проблемы блокирования Блокирование возникает раз, когда сессии не удается получить блокировку ресурса, так как он уже заблокирован дру гой сессией. Блокирование возникает только в том когда типы блокировок, запрошенных несовместимы. В ре зультате одна сессия должна ждать до тех пор, пока другая не освободит блокировку. Например, если сессия А запрашивает монопольную блокировку таблицы А, то никакой сессии 230 Глава не удастся на эту таблицу монопольную блокировку, пока сессия А не снимет свою блокировку.

В зависимости возможно даже после тщательной оптимизации последнего;

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

Определение блокирующих сессий признак лузкого мест, с Ч низкое потребление системных ресурсов (процессора и диска) максимальной пропускной способности SQL-уровня. вы подозреваете, что проблема кроется в блокировании, то всего требуется выполнить запрос к таблице sysprocesses в базе данных master. В листинге 8-1 показан информацию о блокированных сессиях и последний опе ратор, исполненный корневым (root Листинг 8- - Возвращает информацию о блокировании из таблицы SELECT blocked, wait hostname, FROM WHERE blocked DECLARE - Получить spid корневого SELECT = FROM A INNER JOIN В ON = WHERE IF NOT IS NULL BEGIN Возвратить оператор сессии.

Анализ SQL-уровня DBCC END используемый в данной не имеет проблем на SQL-уровне. Однако для моделирова ния блокировки при компиляции мы новую хранимую компилируемую заново при каждом вызове.

приведен сценарий создания такой процедуры:

CREATE PROCEDURE AS SELECT FROM ORDER BY ASC GO Для получения блокировки при компиляции следует выполнить несколько вызовов этой процедуры одновременно. Как говори лось в главе 3, для моделирования нагрузки на SQL-сервер мы можем использовать ACT. сценарий ACT по казан в листинге 8-2.

Листинг 8- -- Сценарий ACT для вызовов хранимой процедуры.

On Error Resume Next Set = & _ If <> 0 Then Opening connection: & _ & & ELSE 232 Глава If <> 0 Then Executing: & & & End If End IF число одновременных сессий в 10 и вы полните тест в течение пяти минут. Во выполнения нагру зочного теста запуск сценария листинга 8-1 вы получите инфор мацию о блокированных сессиях и последнем операторе, ненном корневым В данном примере столбец сессии должен блокиров ку компиляции:

TAB: 7: ПРИМЕЧАНИЕ Значение "7" после указыва ет базу данных a ком пилируемый объект. В нашем случае "1173579219" соответствует Для получения этой информации достаточно выполнить запрос SELECT в базе данных Store. в что формат поля waitresource может измениться в следующей версии или в следующем пакете в результате чего данный метод определения базы данных и име ни хранимой процедуры станет неприменимым.

Последний оператор, выполненный корневым блокировщиком, должен отображаться Запрос к таблице sysprocesses показал, что проблема связана именно с нашей процедурой, специально добавленной для создания бло кировки.

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

Анализ SQL-уровня Блокировки Глубокое знание типов блокировок, используемых SQL Server, совершенно необходимо поиска и устранения проблем бло Мы настоятельно рекомендуем изучить связанные с блокировками, указанной в главе литературой. Только обладая необходимыми знаниями, вы сможете разрешать проблемы, связанные с тайм-аутами блоки ровок и дедлоками Если в приложении возникает SQL-блокирование, то обычно мы используем для определения полученных и ожидаемых Системная процедура spjock возвращает текущее состояние блокировок на момент ее исполнения, поэтому во вре мя нагрузочного тестирования мы запускаем ее многократно, чтобы определить типовые конфигурации блокировок. Результа ты работы spjock трудно читаемы и требуют дополнительной обработки для получения таблиц и Поэтому для улучшения читабельности результатов мы используем соб ственную хранимую процедуру, аналогичную описанной в The Guide to А теперь мы снова создадим проблему в из хранимых процедур. Ниже приведен сценарий создания такой процедуры:

CREATE PROCEDURE AS -- Транзакция используется для удержания монопольной блокировки, BEGIN TRANSACTION SELECT FROM ORDER BY CategoryName ASC DELAY -- Удерживать блокировку 1 секунду.

COMMIT TRANSACTION GO 234 Глава Исполнение во нагрузочного с помощью приведенной выше процедуры, даст пример но такие результаты:

spid Type Status 51 7 0. DB S GRANT 53 1 0 DB S GRANT 53 i 1977058079 0 RID 1 89:0 Х WAIT 53 1977058079 0 PAG [X GRANT '/ (i GRANT 54 7 1977058079 0 i IX GRANT ;

ХХ 1977058079 о 54 I X GRANT J 0 RID !:89:6 Х GRANT (Результаты приведены частично) Нам интересны столбцы Objld, Type, Mode и Например, в приведенных выше результатах показана монопольная блокиров ка типа (row identifier) для Тип блоки ровки R[D используется вместо типа блокировки KEY в связи с индекса на таблице Кроме того, как показывает значение WAIT в столбце в данный момент ожидается предоставление монопольной Для получения имени объекта можно выполнить запрос SELECT и в данном случае л1977058079 ветствует таблице Categories. Использование результатов запро са к таблице для определения блокирующей сессии в сочетании с результатами вызова хранимой процедуры spjock для получения информации о блокировках проблемы с точностью до конкретного оператора.

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

В строку В и ожидает получения блокировки стро ки А. Каждая из сессий ожидает другую и не может продолжить выполнение, чтобы завершить или отменить транзакцию. Этот тип дедлока называется циклическим. возможный тип Ч дедлок преобразования. Он когда две или несколько Анализ удерживают разделяемые блокировки некоторых ресур сов и хотят свои разделяемые блокировки в нопольные. Независимо от типа дедлока для поиска и устране ния связанных с ним проблем мы используем флаги трассиров ки. Следующий оператор приводит к выводу трассировки дедлока в журнал ошибок SQL Server (3605) и устанавливает этот флаг трассировки для всех сессий DBCC TRACEOMC-1, 1204, 3605) После установки этих флагов трассировки вы можете перехва тить событие ErrorLog с помощью SQL Profiler просмотреть журнал ошибок средствами Enterprise Manager. В демонстраци онных целях мы создали хранимую процедуру, которая вызывает дедлок преобразования:

CREATE CLUSTERED INDEX ON GO CREATE PROCEDURE AS BEGIN TRANSACTION SELECT * FROM WHERE ModelName = Proof Facial DELAY UPDATE SET = UnitCost * 0. WHERE ModelName = Facial COMMIT TRANSACTION GO Для получения дедлока эту хранимую процедуру нужно запустить из двух разных окон SQL Query Analyzer с интервалом в несколь ко секунд. Ниже приведены данные трассировки, полученные путем установки флага Deadlock encountered.... Printing deadlock information graph 236 Глава KEY: 7:2041058307:1 Mode: _ Flags: 0x Grant Mode: Range-S-S Flg:OxO flef:0 Life:02000000 SPID: 52 0 Statement Type: UPDATE Line Input Language Event:

Requested By:

Mode: X SPID: KEY: CleanCnt:2 Range-S-S _ 0x Grant Mode: Range-S-S Ref: SPID: 51 ECID: 0 Statement Type: UPDATE Line Input Language Event:

Requested By:

Mode: X SPID:52 ECID:0 _ Victim Resource Owner:

Mode: X SPID:52 ECID:0 _ Cost:(0/0) Флаг генерирует подробную информацию о каждом возник новении дедлока, мы же обычно исследуем только часть этих данных. Нас интересуют блокируемый ресурс тип блоки ровки и имя хранимой процедуры либо произвольный запрос Input Имея эту информацию, ограничить область дальнейших несколькими хранимыми процеду рами или запросами. Более подробную информацию о борьбе с дедлоками и флаге трассировки 1204 см. в SQL Server Books Online u Inside Microsoft SQL Server 2000.

Дополнительные ресурсы Ранее мы уже рассказывали о том, как бороться с проблемами вручную. Используя специальные сценарии, вы влияние фактора человеческих ошибок. Эти сценарии поиска опубликованы в следующих статьях.

Анализ SQL-уровня Х INF: How to Monitor SQL Server 2000 Blocking no адресу kb;

en Х INF: SQL Blocking Due to Locks no адресу = kb;

en Х INF;

Troubleshooting Application Performance with SQL Server no адресу ult.aspx?scid = Настройка индексов в предыдущем разделе, ог раничить область поиска проблем конкретными запросами хранимыми процедурами. Выявив SQL-команду, вызывающую вы сделаете большой шаг вперед на пути к ее нию. К практически невозможно перечислить все проблемы, которые могут возникнуть при работе с SQL Ser ver 2000. Каждый наша группа обнаруживает новые слож ные проблемы, и чем больше мы работаем с SQL Server, тем боль ше убеждаемся в том, что теоретических знаний, почерпнутых из книг и статей, недостаточно того, чтобы стать экспертом настройке производительности SQL Server, Поэтому, если вам не удалось решить конкретную проблему производительности сра зу же по прочтении этой главы, не просто пой мите, что за один научиться для SQL Server.

Другая проблема, хорошо знакомая нам, Ч отсутствие необхо димых индексов. Обычно мы используем сходные методы на стройки индексов для каждой SQL-команды. Мето ды, которые мы применяем для настройки обсужда ются в следующем разделе.

Анализ планов Одним из способов выявления причин долгого исполнения за проса является анализ плана выполнения запроса и проверка ме тода выборки данных, использованного оптимизатором запросов SQL Server 2000. Для получения графического представления плана выполнения вы можете применять Query Analyzer.

238 Глава Генерация данных Прежде чем мы добавим строк в таблицу и строк в таблицу базы данных сайта-при мера IBuySpy. Фактическое число строк для анализа SQL-уровня зависит от и предполагаемых темпов роста базы данных. Мы выбрали число строк произвольно, только бы продемонстрировать, как выполнять анализ на больших на борах данных. В зависимости от числа строк и уникальности дан ных по столбцам SQL Server ведет себя no-разному;

поэтому не обходимо использовать для настройки базу данных ющих размеров. В листинге 8-3 показан генерации тестовых строк.

Листинг 8- Ч Сценарий генерации тестовых данных, SET ON - Отключить вывод сообщений о числе строк, DECLARE DECLARE int DECLARE int DECLARE int int DECLARE Определить число строк перед вставками.

SELECT Orders FROM Orders SELECT OrderDetails FROM OrderDetails SELECT FROM Customers SET = SET = -- Добавить 100000 строк в Orders и 10000 строк в Customers.

WHILE <= BEGIN - Каждые 10 строк вставлять нового клиента.

IF 10 = О OR = BEGIN INSERT INTO Customers Анализ SQL-уровня Password ) VALUES + as + as + SET = END -- Задать для OrderDate и ShipDate.

SET = (-1 * Л SET = (-1 - X INSERT INTO Orders С OrderDate, ShipDate VALUES ( SET = SET = INTO OrderDetails С Quantity, UnitCost SELECT TOP ProductID, 1, UnitCost FROM Products ' - 4 разных сортировки для разных товаров.

4 = 240 Глава SET = + BY IF % 4 = SET + N'ORDER BY IF 4 = SET = + N'ORDER BY IF X 4 = SET = + N'ORDER BY EXEC sp_executesql int', _ = SET = + END - Число строк после вставок.

SELECT Orders FROM Orders SELECT OrderDetails SELECT Customers FROM Customers Просмотр плана выполнения После загрузки тестовых данных выполним процедуру Ч одну из хранимых процедур, на работу которых значительно влияет увеличение размера базы данных. Для полу чения плана в Query следует включить оп цию Show Execution Plan (нажмите CTRL+K). План выполнения процедуры показан на рис.

В этом относительно простом примере вы так:

CREATE Procedure ProductsMostPopular AS SELECT TOP as FROM OrderDetails INNER JOIN Products ON = SQL-уровня GROUP BY ID, ORDER BY DESC GO Рис. План выполнения хранимой процедуры Различных для представления физических операций, используемых при SQL-операторов, слишком чтобы перечислять их здесь все. Они подробно описаны в SQL Books Online, где, кроме того, подробно рассказано о том, как интерпретировать графическое представление плана. В этом разделе мы рассмотрим лишь те причины, которые значительно увеличивают время исполнения запроса.

Из различных физических операторов следует уделить внимание относительно дорогим. Например, на рис. 8-1 больше остальных стоят операторы Hash Match/Aggregate и Table Scan: 54 и 46% 242 соответственно. При наведении указателя мыши на каждый зна чок в плане выполнения на экране отображается под сказка, содержащая подробную информацию. На рис. 8-2 показа на такая подсказка для значка Table Scan.

Г able Table Table row CPU 0. of f L >D Рис. 8-2. Всплывающая для значка Table Scan В подсказке говорится, что оптимизатор запросов для считыва ния данных из выбрал опера тор Table Scan. В типичных случаях использование Table Scan и Index Scan увеличивает время исполнения по сравнению с Index Seek. Однако в нашем случае для определения пяти наиболее популярных товаров необходимо считывать всю таблицу Order Использование Table Scan и Index Scan для небольших таблиц правомочно и в некоторых случаях более эффективно. На личие таких операторов в плане не является осно ванием для реакции Ч создание дополнительных индексов для маленьких таблиц иногда не дает никакого резуль тата с точки зрения времени исполнения запроса. Таким образом, помимо списка физических операторов для эффективной на стройки индексов вам потребуется дополнительная информация.

Анализ SQL-уровня ПРИМЕЧАНИЕ Сканирование применяется для таб лиц без кластерных Следствием отсутствия кластерного индекса может быть плохая производи тельность. Подробнее о проблеме Ч в Poor Performance on a Heap на странице com/default.aspx?scid = Дополнительная информация для настройки SQL Server предоставляет полезные возможности сбора статис тики, позволяющие определять объемы потребляемых ресурсов, например STATISTICS Комбинированный анализ плана выпол нения запроса и статистики предназначен для определения таб лиц, проблемы производительности. Так как конеч ной целью сокращение времени исполнения запросов, это время измерить. Для этого следует опцию TIME. Теперь на экране отображается время разбора и компиляции что позволяет определить дли тельность генерации плана выполнения.

СОВЕТ Длительность исполнения запросов опре деляют с помощью SQL Profiler;

опция позволяет просматривать ность выполнения в том же окне, в котором няется запрос.

Кроме того, предусмотрены две команды очищающие буфер данных и кэш процедур: DROPCLEANBUFFERS дает возможность тестировать запросы при незаполненном буфере данных без необходимости перезапуска SQL Server, что позволя ет получать сравнимые статистических параметров за проса, a DBCC FREEPROCCACHE предназначена для тестирова ния производительности запросов при заполненном и незапол ненном кэше процедур.

При реальной эксплуатации приложения команд DBCC и DBCC FREEPROCCACHE избегать.

244 Глава Рассмотрим показатели производительности, полученные при хранимой процедуры в Query Analyzer с следующего сценария:

FREEPROCCACHE SET STATISTICS ON SET STATISTICS ON GO EXEC Объем информации, командами DBCC и опция ми разнится в от сложности процедуры. Для ProductsMostPopular интересующая нас часть результатов ниже:

SQL Server parse and compile time:

CPU time = 32 time = 187 ms.

(5 affected) Table Scan count 5, logical reads 10, physical reads 4, read-ahead reads 0.

Table Scan count 1, logical reads 3800, physical reads 0, read-ahead reads 3801.

SQL Server Execution Times:

CPU time = 1813 ms, elapsed time = 1826 ms, (Результаты приведены частично) Значения статистических параметров различаются в ти от размера базы данных, версии SQL Server и конфигурации аппаратных средств. Полученные нами результаты показывают, что на разбор и компиляцию хранимой процедуры затрачено 187 миллисекунд, а на ее выполнение Ч миллисекунд. Эта информация о исполнения лучена включением опции STATISTICS TIME. Наиболее интересна та часть результатов, где указано значение logical reads для таб лицы OrderDetails. Это число страниц, считанных из буфера;

зна чение 3800 в сравнении с аналогичным значением для таблицы Анализ SQL-уровня Products подтверждает предположение о том, что использование оператора Table Scan для выборки данных неэффективно. Иног да также полезно значение параметра scan count. Оно соответ числу обращений к объекту и напрямую связано с типом используемого соединения (join). Например, значение scan count запроса, использующего циклическое соединение (loop join) и возвращающего 100 строк, может быть равно 100, тогда как для того же запроса, использующего соединение слиянием (merge join), scan count может быть равен В нашем случае значения данного параметра неинтересны, так как довольно малы. Значе ния physical reads и read-ahead reads зависят от того, считаны ли уже необходимые данные в буфер или нет. С точки зрения настройки производительности запросов эти два параметра не представляют интереса.

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

Индексы Если вы уже работали раньше с SQL Server, то, вероятно, слыша ли о кластерных и некластерных индексах. Глубокое понимание хранения и использования индексов совершенно необ ходимо для их настройки. Подробное обсуждение индексов в SQL Server выходит за рамки данной книги. В табл. 8- приведена общая информация о каждом типе индексов.

8-2. Типы индексов SQL Server Типы индекса Описание Кластерный Таблица физически по столб цов индекса. Индексы этого типа содержат все дан ные таблицы. Кластерный индекс создается автома тически при создании первичного ключа, если явно не указано иное см. след. стр.

246 8-2.

Типы индекса Описание Некластерный Данные таблицы не содержатся внутри индекса, просто индекс содержит указатели на место располо жения данных таблицы. При обращении к столбцу, не в индекс, выполняется операция поиска по закладке (Bookmark Lookup) в таблице, организо виде или в кластерном индексе Правильный выбор индексов В реальной ситуации выбрать правильный индекс не так-то и просто. При этом нельзя рассмотрением только плохо работающего запроса, гак как изменение индексов может повлиять на другие запросы, которые их используют. Например, если время исполнения запроса снижается при создании новых индексов, то время исполнения запросов DELETE или в некоторых случаях вырастает. Еще больше влияет на ситуацию создание индекса по часто столб цу. При изменении столбца для сохранения порядка в индексе потребуется перемещение индексных записей, в резуль тате чего дополнительные задержки для больших таб лиц. Транзакции, длительное время, способны на долго захватывать монопольные блокировки, что приводит к воз никновению лузких мест в результате блокирования других По счастью, как мы уже упоминали в главе 3, реальные сцена рии пользовательских действии можно записать и использовать з нагрузочных тестах. В этом случае вы можете легко выполнить повторные тесты и результаты после каждого измене ния. Исполнение нагрузочных тестов позволит найти лузкие места и снизить риск порождения новых проблем из-за измене ний в индексах. Кроме того, вам удастся измерить общий при рост производительности в результате каждого изменения. В демонстрационных целях все наши примеры настройки сов используют один запрос.

Некластерный индекс Некластерный индекс не содержит все данные таблицы, а ко копии данных из выбранных столбцов и указатели на положе ние остальных данных Положение может быть ключом Анализ SQL-уровня кластерного индекса идентификатором строки, если у табли нет кластерного индекса. Эти свойства некластерного индекса позволяют сделать его компактным, в результате чего вание всего дерева индекса требует небольшого числа операций чтения страниц, по сравнению со сканированием кластерного декса. при выборке диапазона данных, если все требуемые столбцы входят в состав некластерного индекса, он работает быстрее кластерного.

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

Хотя в нашу задачу не входит описание всех возможных вариан тов применения некластерного индекса, мы рассмотрим покры вающие (covering) индексы, с которыми имеем дело чаще всего.

называется индекс, все столбцы, используемые в запросе. При правильном применении, благода ря ликвидации необходимости поиска по закладке, индекс существенно повышает производительность запроса. Так как некластерный индекс не содержит иных данных таблицы, помимо индексированных то любое обращение к дру гим столбцам потребует выборки их данных либо из кластерно го индекса, либо из кучи. Введение в индекс дополнительных колонок, не используемых в аргументах поиска (Searchable Arguments, 5ARG) или условиях соединения, позволяет получить все данные из некластерного индекса без дополнительного поиска.

Покрывающий пример Из приведенного ранее анализа плана выполнения хранимой про цедуры ProductsMostPopular следует, что большинство логичес ких операций выполняется для таблицы Сна чала получим информацию об индексах этой таблицы, выполнив следующий оператор:

OrderDetails Получим один некластерный индекс на столбцах OrderlD и Более того, поле index_description говорит о том, что это ограничение первичного ключа. На основании информации об индексе и запросе, используемом в ProductsMostPopular, мож но построить табл. 8-3, которая позволит определить, какие стол бцы и в каком порядке следует использовать.

248 Глава 8-3. Слисок и порядок выбранных столбцов Таблица OrderDetails Столбцы Аргумент поиска (SARG) Нет GROUP ORDER BY D JOIN ProductID Другие, используемые Sum(Quantity) запросом, столбцы индекс Первичный ключ, некластерный индекс no ProductID) Быстрые клавиши Хранимые процедуры или операторы SQL сохраняют сред окна Customize, из меню Tools. Далее хранимую можно Например, как на рис. 8-3, можно зать Ft.

Рис. Окно Customize быстрые клавиши для вызова хранимых процедур Анализ Когда в следующий раз вы захотите выделить имя вас и CTRL F1. Быстрые клавиши очень удобно вать с и Как видно из табл. некластерный индекс по ductlD и Quantity мог бы покрыть все Кроме того, так как ProductID используется в выражении CROUP BY, то в котором ProductID следует первым, оказался бы более эффек тивным, чем тот, в котором сначала идет Quantity. Тем не менее создадим два индекса с разным порядком столбцов и посмотрим, какой из них окажется эффективнее. Используем следующий сценарий:

CREATE INDEX ON (ProductID, Quantity) CREATE INDEX ON OrderDetails ProductID) Теперь, когда мы снова запустим оптимиза тор запросов выберет другие операторы и покрывающий индекс по полям ProductID и Quantity. Сервер используем тот же на базе 1 -гигагерцового Pentium. Новый план показан на рис. 8-4.

Вместо оператора Table Scan теперь задействован Index Scan, a Hash Match/Aggregate Ч Stream Aggregate. Для сравнения двух покрывающих индексов использован совет оптимизатору, который показан полужирным шрифтом в следующем фрагмен те кода:

SELECT TOP as FROM OrderDetails INNER JOIN ON = _ BY 250 Глава ORDER BY DESC 8-4. План исполнения после создания покрывающих индексов для таблицы OrderDetails ПРИМЕЧАНИЕ В большинстве случаев тор запросов выбирает наиболее эффективные ин дексы и операторы. Однако хорошей практикой тается проверка выбранного плана принудительным заданием альтернативных планов, после чего следу ет сравнить результаты.

В данном примере рассматриваются три плана тистика для каждого из них показана в табл. 8-4.

Как мы и предсказывали, первый покрывающий индекс по стол бцам ProductlD и Quantity дает наилучшие результаты. Фактичес ки при обратном порядке столбцов в покрывающем индексе за Анализ SQL-уровня прос исполняется дольше, чем в индекса. Как види каждое изменение индексов следует тщательно Без этого настройка индексов может снизить производительность приложения.

8-4. Сравнение планов выполнения запросов Покрывающий Покрывающий индекс по индекс по Первоначальный Quantity запрос и Quantity и ProductID Table Scan (46 Index Scan (51 Index Scan стоимость и Hash Match/ и и Hash (38 %) выбранных Aggregate (54 Aggregate (49 %) Match/Aggre операторов gate ( Число логических 3800 2184 чтения no Длительность 1826 1021 исполнения, мс В данном примере применение покрывающего индекса позволило сэкономить примерно 800 миллисекунд. В обычном случае мы продолжили анализ запроса, чтобы определить, нельзя ли еще повысить скорость исполнения запроса с помощью индексиро ванного представления. Индексированные представления для кластерных индексов рассматриваются в разделе, посвященном кластерным индексам.

Покрывающий индекс: пример В этом примере мы рассмотрим хранимую процедуру Запрос возвращает историю заказов клиента и требует Custo в качестве параметра. Ниже приведен сценарий исполне ния процедуры:

DBCC GO SET STATISTICS ON SET STATISTICS TIME ON GO EXEC Следуя тому же что и в примере мы получаем статис тику запроса, включив и и рассмат риваем план STATISTICS TIME позво установить, что запрос примерно 640 миллисе кунд. Это не так уж долго по с однако план выполнения показывает, что операто ры Table Scan и Bookmark Lookup, из чего обычно следует необ ходимость индексов. Предположим, что OrdersList исполняется часто и требует настройки. Нам необходимо проана лизировать, какие столбцы использует процедура OrdersList. При исполнении системной процедуры с OrdersList в качестве параметра выводится следующий текст;

CREATE Procedure OrdersList ( int As SELECT as money) as FROM Orders INNER ON = GROUP BY CustomerlD, HAVING = На основании анализа кода OrdersList мы можем построить сле дующие таблицы, аналогичные табл, 8-5:

SQL-уровня 8-5. Столбцы таблицы Orders используемые Таблица Orders Столбцы Аргумент поиска (SARC) CustomerlD GROUP BY или ORDER BY CustomerlD, ShipDate OrderlD Другие, запросом, столбцы Нет индекс Нет 8-6. Столбцы таблицы OrderDetails используемые Orders List Таблица Столбцы Аргументы песка (SARG) Нет GROUP BY или ORDER BY Нет JOIN OrderlD используемые запросом, столбцы индекс Первичный ключ, неклас терный индекс по (OrderlD, ProductID) СОВЕТ Настоятельно рекомендуем особенно при анализе более сложных записывать все используемые столбцы таблицы.

Аналогично первому примеру с индексом мы мо жем создать на основании табл. 8-5 и 8-6 следующие два покры индекса;

CREATE INDEX ON OrderDetails ShipDate) CREATE INDEX ON OrderDetails (OrderlD, Quantity, полученная до и после создания покрывающих ин дексов, приведена в табл. 8-7.

Как из табл. применение покрывающих индексов ус корило запрос почти в сто раз. Наш опыт показывает, что созда ние подходящих покрывающих индексов нередко позволяет до 254 Глава таких грандиозных улучшений. что это улучшение для одной, изолированно исполняющейся хра нимой процедуры. Прежде чем переносить новые индексы из тестовой базы в рабочую, необходимо тщательно протестировать общую производительность приложения на типовых сценариях пользовательской активности.

8-7. Сравнение статистики разных планов выполнения Первоначальный С покрывающими вариант индексами Относительная стоимость Table Scan no Index Seek no выбранных Orders (22 Orders ( Bookmark Lookup no Index Seek no OrderDetails (75 ( Число логических Orders 520 Orders = чтения OrderDetails Длительность 644 Кластерный индекс Так как кластерный индекс физически сортирует данные табли то в таблице не может быть больше одного такого индекса.

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

Средствами SQL Server легко создать кластерный индекс для каж дой таблицы Ч по умолчанию при определении ограничения вичного ключа. Сложно выбрать набор столбцов кластерного индекса. Описание всех вариантов применения кла стерного индекса выходит за рамки данной главы. Здесь мы рас смотрим только вопросы, которые, по нашему опыту, разработ чики часто упускают из виду:

Анализ SQL-уровня Х параметр Х кластерный индекс для представления, Рассмотрим каждый из этих случаев на конкретном примере.

FILLFACTOR Параметр FILLFACTOR задает объем пространства, мого на каждой странице. Например, значение 80 зарезервиру ет 20% свободного пространства, что примерно равно 1,6 кбайт.

Это полезно для таблиц или индексов со вставок и обновлений. Наличие дополнительного свободного пространства позволяет уменьшить частоту реорганизаций, разбиения, страниц (page split), вызываемых операциями вставки или обнов ления на заполненной странице. Предположим, например, что в о клиентах поле адреса, которое при создании записи о клиенте остается пустым. Если страница, содержащая такую запись, заполнена или почти заполнена, то обновление информации адреса потребует дополнительного про странства и вызовет разбиение страницы.

Последнее, в свою очередь, чревато фрагментацией и уменьше общей плотности хранения данных. Если из-за большого числа разбиений страниц они заполнены только на то для хранящихся в них данных потребуется вдвое больший объем операций ввода-вывода по сравнению со заполнением страниц. Резервирование свободного пространства на странице выгодно для приложений с большим числом вста вок и обновлений, благодаря уменьшению числа разбиений ниц и степени вызванной этими разбиениями фрагментации. Так как FILLFACTOR гарантирует наличие свободного пространства только во время создания, необходим периодически фрагментации таблиц и индексов, а также плотности страниц.

Команда позволяет получить информацию о фрагментации и плотности данных в таблицах и индексах. Что бы продемонстрировать эффект фрагментации, мы немного модифицируем таблицу Orders в базе данных сайта-примера код добавляет поле описания, допускающее значения и кластерный индекс по столбцу OrderlD:

ALTER TABLE Orders ADD NULL 256 Глава CREATE CLUSTERED ON Orders GO Использовав код листинга мы можем измерить дительность запроса при разных уровнях фрагментации:

Листинг 8- - Сбор производительности запроса при разной фрагментации.

-- Очистка кэша буферов данных и планов DBCC FREEPROCCACHE GO - Включить отображение статистики ввода-вывода и времени.

SET STATISTICS ON SET STATISTICS TIME ON GO - Запрос к таблице Orders.

SELECT TOP 10 WITH TIES CustomerlD, _ MaxShippingDelay FROM Orders GROUP BY CustomerlD ORDER BY MaxShippingDelay DESC, CustomerlD GO - информацию о фрагментации для таблицы Orders.

DBCC GO Ниже показан фрагмент результатов работы кода из листинга 8-4:

scanning table...

(2025058250);

index ID: 1, database TABLE level scan performed.

- Pages : - Extents Scanned : - Extent Switches ;

- Avg. Pages per Extent ;

7. - Scan Density [Best Count] ;

[53:54] - Logical Scan Fragmentation :

- Extent Scan Fragmentation :

- Avg. Bytes Free per Page : 25. Avg, Page Density (full) :

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Анализ SQL-уровня Table Scan count logical reads 419, physical reads 0, read-ahead reads 0.

SQL Server Execution CPU time = 297 elapsed = приведены частично) Наиболее частью результатов работы Scan Density (плотность сканирования) и Avg.

Page Density (средняя плотность страницы). Плотность сканиро вания отражает смежность ссылок на экстенты: чем больше фрагментация таблицы, меньше плотность сканирования.

выборки данных из менее таблиц потре буется меньше экстентов.

Чем ближе средняя плотность страницы к тем меньше операций требуется на считывание данных из таб лицы. Это связано с используемым SQL Server методом выборки данных со страницы;

независимо от степени ее заполнения, вся 8-килобайтная страница считывается целиком. В нашем случае оба значения плотности оптимальны. Теперь посмотрим, что про изойдет, если изменить содержимое столбца OrderDesc в каждой строке таблицы Orders. этого выполним следующие операторы:

- Использование функции REPLICATE здесь не необходимос тью, но -- она может быть вам полезна для генерации тестовых данных.

UPDATE Orders SET OrderDesc = description ' + 10) WHERE OrderlD X 10 = Снова выполним код листинга 8-4 и проанализируем производи тельность запроса и уровень фрагментации табли цы Orders. Результаты теперь будут такими:

Table: (2025056250);

index ID: 1, database ID: TABLE level scan performed.

- Pages Scanned : - Extents Scanned : - Extent Switches :

- Avg. Pages per Extent : 7. - Scan Density [Best Count] :

258 Глава - Logical Scan Fragmentation :

- Extent Scan Fragmentation :

- Avg. Bytes Page :

- Avg. Page Density (full) execution completed. If printed error messages, contact system administrator.

Table Scan count logical reads 836, _ physical reads 0, read-ahead reads 0.

SQL Server Execution Times:

CPU time 307 elapsed time = 307 ms.

(Result abbreviated) После того как мы искусственно ско рость исполнения запроса существенно не изменилась;

однако количество логических операций чтения почти удвоилось: против 419. В основном это с уменьшившейся средней плотностью страницы, которая с 99% снизилась до 53%. В дан ном случае длительность запроса для одного пользо вателя. С увеличением числа пользовательских сессий негатив ное дополнительных операций записи проявится в даль росте времени исполнения запроса.

Мы могли бы избежать фрагментации, если бы для кластерного индекса таблицы Orders был равен 90%.

но несколько способов изменения FILLFACTOR. Можно удалить кластерный индекс и заново создать его, задав при этом ние равное либо изменить FILLFACTOR с помо щью DBCC REINDEX, Подробнее см. и CREATE INDEX в SQL Books Online.

Индексированные относятся к новым средствам SQL Server 2000 Enterprise Edition. В предыдущих версиях SQL Server при каждом обращении к представлению запросе сер веру приходилось считывать данные из базовых таблиц представ ления. Однако при использовании индексных представлений ре зультаты вычисляются до того, как представление использовано каким-либо запросом. В зависимости от степени накладных связанных с данных из базовой таблицы, мате Анализ наборы результатов могуть огромный при рост производительности запросов. В этом примере мы продол рассмотрение первого примера для некластерного индекса и продемонстрируем использование индексного представления.

По нашему опыту, индексные дают существенный прирост производительности при использовании в запросах с такими агрегатными функциями, как SUM и COUNT.

SUM используется Popular приложения Показанный далее запрос является фрагментом этой процедуры:

SELECT TOP as TotalNum, FROM INNER JOIN Products ON = _ GROUP BY ORDER BY TotalNum DESC На основании запроса, используемого в создадим представление и уникальный кластерный индекс, как показано на листинге 8-5.

Листинг 8- - Установка опций, требуемых для индексированных - представлений.

SET ON SET ARITHABORT ON SET ON SET ANSI_NULLS ON SET ON SET ON SET OFF GO 260 Глава if exists (select * where id = and _ OBJECTPROPERTY(id, = 1) drop view GO CREATE VIEW WITH AS SELECT OrderSum, Требуется агрегирующая функция FROM od INNER JOIN p ON od.productid = GROUP BY GO - индекс на индексированном представлении обязан быть - уникальным и CREATE UNIQUE CLUSTERED INDEX ON создании индексированного убедитесь в пра вильной установке пользовательских опций. Обязатель ные пользовательские опции показаны на рис. 8-5. Кроме того, представление необходимо создавать с атрибутом DING. И наконец, первый индекс представления должен быть уникальным кластерным индексом. После создания кластерного индекса, если требуется, можно создать дополнительные стерные индексы. Более подробную информацию об ванных представлениях и о связанных с ними требованиях см. в SQL Server Books Online. После создания индексированного ставления мы можем снова процедуру и как изменилась производительность. Па раметры производительности сравниваются в табл. 8-8, Как из нее видно, использование индексированного представле ния ProductOrderCount существенно снизило длительность испол нения запросов и число логических операции чтения. На самом деле операции чтения теперь не для таблицы Order Details, но для представления ProductOrderCount. Ниже показа ны результаты IO, полученные при исполнении Анализ (5 affected) Table Scan count 1, logical reads physical reads 0, read-ahead reads 0.

(Результаты приведены частично) 8-8. Сравнение производительности при использовании представления Покрывающий индекс для Первоначальный D Индексированное вариант и Quantity представление Относительная Table Scan (46 Index Scan Clustered Index стоимость u Hash Match/ (51 u Stream ( Aggregate Aggregate u Sort ( ( Число логичес- 3800 2184 чтения таблицы Длительность 1826 1021 мс Если бы оставалась единственной хранимой исполняемой то можно было бы ти к выводу, что индексированное представление наи лучшим решением. В реальных приложениях хранимая процеду ра обычно не одна. Индексированные представления способны радикально повысить производительность чтения, однако при этом зачастую также снижается производительность запросов, обновление данных. Следовательно, прежде чем окончательно принять решение об использовании индексирован ного необходимо провести дополнительное зочное тестирование и убедиться в том, что общая пропускная способность приложения возросла.

В поставку SQL Server включен мастер Index Tuning, который в некоторых случаях поможет вам выбрать эффективные индек сы. Интересно мастер Index Tuning для анализа полнения процедуры этого запустите 262 Глава мастер из Query Analyzer (нажмите Для мастер порекомендует вам практически идентичное ин дексированное представление. Во многих случаях использование мастера Index Tuning сэкономит время и даст полезную инфор мацию об индексах. Если вам раньше не приходилось работать с этим мастером, рекомендуем за дополнительной ин формацией обратиться к соответствующим разделам SQL Server Books Online. статься, посвященная этому масте ру, также опубликована в Microsoft Примерами, приведенными в этой главе, ни в коей мере не ис черпываются все возможные случаи настройки индексов Ч мы хотели только продемонстрировать вам общее представление о важности правильной настройки индексов. Простая ошибка создании индексов или отсутствие необходимых индексов может полностью парализовать работу сервера при больших транзакций. Оценка всех индексов в базе данных, содержащей множество других весьма утомительное занятие, но она того стоит. В большинстве случаев база данных с правильно по строенными индексами в перспективе создаст вам меньше про блем. При анализе лузких мест в SQL мы настоятельно рекомен дуем вам сначала индексы и только потом пытаться вносить изменения в запросы или устанавливать дополнительное оборудование.

Заключение В этой главе мы рассказали о способах выявления лузких мест на SQL-уровне. Были рассмотрены инструментальные средства для мониторинга работы сервера и выявления лузких мест, а также способы анализа и устранения часто возникающих про блем. Несомненно, для полного изучения SQL Server вам потре буется время и опыт, Прочитав эту глазу, вы не станете в одно часье экспертом, но несомненно узнаете, как выявлять места и быстро исправлять распространенные проблемы произ водительности на SQL-уровне.

Глава По словам Джонатана Свифта, необходимость Ч изобре тения, но при планировании пропускной способности больше подходят слова Марка Твена: Необходимость Ч мать риска.

Почему? Потому что расчет пропускной способности Ч это кусство уменьшить вероятность того, что быстродействие Web приложения снизится из-за увеличения трафика или изменения его характера, и в то же время избежать дополнительных затрат на оборудование. Microsoft Transaction Cost Analysis (TCA) Ч ана лиз стоимости транзакции Ч это основанная на научных ботках методика, оценить потребности Web-прило жения в Но никогда нельзя быть абсолютно уве ренным в том, как пользователи на работу вашего Web приложения. Будьте готовы к сюрпризам.

Pages:     | 1 | 2 | 3 | 4 |    Книги, научные публикации