Поделиться через


Производительность CLR-интеграции

В этом разделе рассматриваются некоторые варианты проектирования, которые повышают производительность интеграции Microsoft SQL Server с средой CLR microsoft .NET Framework.

Процесс компиляции

Во время компиляции выражений SQL при обнаружении ссылки на управляемую подпрограмму создается заглушка промежуточного языка Майкрософт (MSIL). Эта заглушка включает код для маршалирования параметров подпрограммы из SQL Server в среду CLR, вызова функции и возврата результата. Этот код "клей" основан на типе параметра и направлении параметров (в, вне или ссылке).

Код клея обеспечивает оптимизацию с учетом типов и обеспечивает эффективное применение семантики SQL Server, например nullability, ограничение аспектов, по значению и стандартной обработке исключений. Создавая код для конкретных типов аргументов, можно избежать приведения типов и нагрузки по созданию объектов-оболочек (этот процесс называют также «упаковкой») при вызове, пересекающем границы процессов.

Затем созданная заглушка компилируется в машинный код и оптимизирован для конкретной аппаратной архитектуры, на которой выполняется SQL Server, с помощью служб компиляции JIT (JIT) среды CLR. Службы JIT вызываются на уровне метода и позволяют среде размещения SQL Server создать одну единицу компиляции, которая охватывает выполнение SQL Server и СРЕДЫ CLR. После компиляции заглушки результирующий указатель на функцию становится реализацией этой функции времени выполнения. Этот подход создания кода гарантирует отсутствие дополнительных затрат на вызов, связанных с отражением или доступом к метаданным во время выполнения.

Быстрые переходы между SQL Server и СРЕДОЙ CLR

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

Рекомендации по производительности

Ниже приведены рекомендации по повышению производительности, относящиеся к интеграции среды CLR в SQL Server. Дополнительные сведения см. на веб-сайте MSDN в разделе "Использование интеграции СРЕДЫ CLR в SQL Server 2005". Общие сведения о производительности управляемого кода см. в статье "Улучшение производительности приложений и масштабируемости приложений .NET" на веб-сайте MSDN.

Пользовательские функции

Функции CLR получают более быстрый путь вызова, чем Transact-SQL определяемых пользователем функций. Кроме того, управляемый код имеет решающее преимущество производительности по сравнению с Transact-SQL с точки зрения процедурного кода, вычислений и строковых манипуляций. Функции СРЕДЫ CLR, которые являются вычислительными и не выполняют доступ к данным, лучше написаны в управляемом коде. Однако функции Transact-SQL выполняют доступ к данным более эффективно, чем интеграция СРЕДЫ CLR.

агрегаты User-Defined

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

Функции потоковой передачи Table-Valued

Часто бывает нужно, чтобы в результате вызова функции приложение вернуло таблицу. Например, в качестве части операции импорта приложение читает табличные данные из файла; нужно преобразовать их из формата величин с разделителями-запятыми в реляционное представление. Обычно это достигается с помощью материализации и заполнения таблицы результатов до ее использования вызывающим объектом. Интеграция СРЕДЫ CLR с SQL Server представляет новый механизм расширяемости, называемый функцией потоковой передачи с табличным значением (STVF). Управляемые функции потока, возвращающие табличное значение, по производительности опережают реализации на основе расширенных хранимых процедур.

Потоковые функции с табличными значениями — это управляемые функции, которые возвращают интерфейс IEnumerable. У интерфейса IEnumerable есть методы для навигации по результирующему набору, возвращенному потоковой функцией с табличными значениями. При вызове возвращающей табличное значение функции потока возвращенный интерфейс IEnumerable непосредственно соединен с планом запроса. Когда плану запроса нужно получить строки, он вызывает методы интерфейса IEnumerable. Такая модель итерации позволяет провести немедленную обработку результатов сразу после получения первой строки, не ожидая заполнения всей таблицы. Она также существенно снижает затраты памяти на вызов функции.

Массивы и курсоры

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

Строковые данные

Данные символов SQL Server, например varchar, могут быть типа SqlString или SqlChars в управляемых функциях. Переменные SqlString создают экземпляр всего значения в память. Переменные SqlChars предоставляют интерфейс потоковой передачи, который можно использовать для повышения производительности и масштабируемости, не создавая экземпляр всего значения в память. Это особенно важно для данных больших объектов (LOB). Кроме того, с помощью потокового интерфейса, возвращаемого методом SqlXml.CreateReader(), можно получить доступ к XML-данным на сервере.

СРЕДА CLR и расширенные хранимые процедуры

Интерфейсы программирования приложений Microsoft.SqlServer.Server (API), которые позволяют управляемым процедурам отправлять результирующие наборы клиенту лучше, чем API Open Data Services (ODS), используемые расширенными хранимыми процедурами. Кроме того, API System.Data.SqlServer поддерживают такие типы данных, как , varchar(max)nvarchar(max)и varbinary(max), представленные в SQL Server 2005 (9.x), в то время как xmlAPI ODS не были расширены для поддержки новых типов данных.

С помощью управляемого кода SQL Server управляет использованием таких ресурсов, как память, потоки и синхронизация. Это связано с тем, что управляемые API, предоставляющие эти ресурсы, реализуются на основе диспетчера ресурсов SQL Server. И наоборот, SQL Server не имеет представления или управления использованием ресурсов расширенной хранимой процедуры. Например, если расширенная хранимая процедура потребляет слишком много ресурсов ЦП или памяти, невозможно обнаружить или контролировать ее с помощью SQL Server. Однако с помощью управляемого кода SQL Server может обнаружить, что данный поток не предоставляется в течение длительного периода времени, а затем принудительно принудить задачу к получению, чтобы другая работа была запланирована. Следовательно, использование управляемого кода обеспечивает более высокую масштабируемость и использование системных ресурсов.

Управляемый код может привести к дополнительным затратам, необходимым для поддержания среды выполнения и выполнения проверок безопасности. Это так, например, при выполнении внутри SQL Server и многочисленных переходов из управляемого в машинный код (так как SQL Server должен выполнять дополнительное обслуживание параметров, относящихся к потоку, при переходе в машинный код и обратно). Следовательно, расширенные хранимые процедуры могут значительно опережать управляемый код, выполняемый внутри SQL Server, в случаях, когда между управляемым и машинным кодом возникают частые переходы.

Замечание

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

Собственная сериализация для типов User-Defined

Определяемые пользователем типы (UDT) представляют собой механизм расширения скалярной системы типов. SQL Server реализует формат сериализации для именуемых Format.Nativeпользователей. Во время компиляции структура типа проверяется для создания MSIL, настраиваемой для определения конкретного типа.

Собственная сериализация — это реализация по умолчанию для SQL Server. Сериализация, определяемая пользователем, вызывает для сериализации метод, указанный автором типа. По возможности следует использовать метод Format.Native, так как он обеспечивает наилучшую производительность.

Нормализация сопоставимых определяемых пользователем типов

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

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

Масштабируемое использование памяти

Чтобы управляемая сборка мусора хорошо выполняла и масштабируется в SQL Server, избегайте большого выделения одного выделения. Выделение размером более 88 килобайтов (КБ) будет помещено в кучу больших объектов, что приведет к тому, что сборка мусора будет выполняться и масштабироваться гораздо хуже, чем многие небольшие выделения. Например, если необходимо выделить большой многомерный массив, лучше выделить многомерный массив.

См. также

Типы User-Defined среды CLR