Вначале небольшой контекст, после чего последуют конкретные вопросы.Интеграция CLR SQL Server не вызывает системного времени, как ожидалось
Я пытаюсь создать последовательные GUID для использования в качестве первичных идентификаторов в таблице SQL Server 2008 R2. Раньше они генерировались пользовательской функцией, которая выполняла слишком много операций с строками, чтобы генерировать последовательные GUID, и это было узким местом производительности.
Чтобы уменьшить время выполнения этой функции, я пытаюсь использовать интеграцию CLR и выполнять операции в классе C#. Секвенирование GUID выполняется путем обновления последнего 12 bytes идентификатора GUID до значений, сгенерированных с системного времени.
В начальной версии системная функция SQL Server использовалась для получения времени даты и преобразования ее в тики, которые затем использовались для создания последовательных 12 байтов указателя. Мой подход состоял в том, чтобы использовать свойство .NET Framework DateTime.UtcNow.Ticks
для преобразования в последние 12 байтов, но я заметил, что свойство Ticks
не обновлялось, как ожидалось, и это указывало на то, что функция системного времени не вызывалась так часто, как я ожидал.
Чтобы проверить это, я создал простой метод, который возвращает клещи:
[SqlFunction()]
public static long GetTicks()
{
return DateTime.UtcNow.Ticks;
}
Эту сборку для этого метода затем была создан в качестве ASSEMBLY объекта в SQL Server; обратите внимание, что интеграция CLR была включена, и сборка была создана в режиме UNSAFE
, что позволило получить доступ к OS APIs. Затем я создал функцию в SQL Server и для этой функции CLR:
CREATE FUNCTION GetTicks() RETURNS BIGINT
AS EXTERNAL NAME Sequential.Generator.GetTicks;
GO
Затем я выполнил следующие два оператора с результатами, представленными ниже
SELECT [dbo].[GetTicks]();
SELECT [dbo].[GetTicks]();
Результаты были:
Это показывает, что последовательные вызовы функции CLR возвращали одно и то же значение TICKS. Это означает, что основной вызов ОС не выполнялся для возврата тиков для каждого вызова функции GetTicks()
. Затем я выполнил второе испытание путем создания простой таблицы следующим образом:
CREATE TABLE #tmp1(
[NUM] [INT] NULL,
[TICKS] BIGINT
);
Я населенная таблицу 300 строк, затем выполняется следующее утверждение:
UPDATE #tmp1
SET [ticks] = [Play].[dbo].[GetTicks]();
Я тогда измеренной разницы между [клещами ] значение последовательных строк и существует только одно изменение значений из всех 300 строк (сделано в Excel):
gain, это означает, что свойство Framework DateTime.UtcNow.Ticks
не вызывалось для каждого вызова функции CLR Integrated GetTicks()
.
Есть ли способ, чтобы включить CLR интеграции таким образом, что вызывает к основной ОС может выполняется при каждом вызове функции из SQL Server?
Интеграция SQL CLR неразумного подхода для SQL Server для получения системного времени из ОС на основе более частого, чем функция T-SQL
GetUTCDATE()
?
Спасибо!
(*) Обратите внимание, что последовательные GUID - это требование, я просто пытаюсь максимизировать производительность способа их создания. Кроме того, функция NEWSEQUENTIALID() неприемлема из-за проблем с конфиденциальностью.
* Кроме того, функция NEWSEQUENTIALID() неприемлема из-за проблем с конфиденциальностью. В вашем дизайне есть те же проблемы конфиденциальности. Последовательные идентификаторы в принципе предсказуемы. – SLaks
Кроме того, существуют ограничения на способ вызова NEWSEQUENTIALID(). И это не мой дизайн, но спасибо, что указали это. Но опять же, какие-либо предложения по вопросам интеграции CLR отражены в вопросах? – BgRva