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


Архитектура интеграции со средой CLR — производительность

Область применения: SQL Server Управляемый экземпляр SQL Azure

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

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

Во время компиляции выражений 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, инструкции, содержащие любой управляемый вызов, имеют шаг запуска для идентификации домена целевого приложения. Этот шаг идентификации снижает стоимость перехода для каждой строки.

Performance Considerations (Приложения-функции Azure. Рекомендации по производительности)

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

Определяемые пользователем функции

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

Определяемые пользователем статистические функции

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

Функции потока с табличным значением

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

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

Сравнение массивов и курсоров

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

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

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

Сравнение CLR и расширенных хранимых процедур

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

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

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

Примечание.

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

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

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

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

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

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

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

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

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

См. также

Определяемые пользователем типы CLR