이것은 전통적인 대답은 아니지만 지금까지 언급 한 일부 기술의 벤치 마크를 게시하는 것이 도움이 될 것이라고 생각했습니다. SQL Server 2017 CU9를 사용하여 96 코어 서버에서 테스트하고 있습니다.
많은 확장 성 문제는 일부 전역 상태에서 경합하는 동시 스레드로 인해 발생합니다. 예를 들어, 고전적인 PFS 페이지 경합을 고려하십시오. 너무 많은 작업자 스레드가 메모리에서 동일한 페이지를 수정해야하는 경우에 발생할 수 있습니다. 코드의 효율성이 높아지면 래치를 더 빨리 요청할 수 있습니다. 그것은 경합을 증가시킵니다. 간단히 말해서, 효율적인 상태의 코드는 글로벌 상태가 더 심각하게 경쟁하기 때문에 확장 성 문제로 이어질 가능성이 높습니다. 글로벌 상태에 자주 액세스하지 않기 때문에 느린 코드는 확장 성 문제를 일으킬 가능성이 적습니다.
HASHBYTES
확장 성은 입력 문자열의 길이를 부분적으로 기반으로합니다. 내 이론은 이것이 발생하는 이유에 대한 것인데 HASHBYTES
함수가 호출 될 때 일부 전역 상태에 대한 액세스가 필요하다는 것 입니다. 관찰하기 쉬운 전역 상태는 일부 SQL Server 버전에서 호출 당 메모리 페이지를 할당해야한다는 것입니다. 관찰하기 어려운 것은 일종의 OS 경합이 있다는 것입니다. 결과적으로 HASHBYTES
코드에서 덜 자주 호출 하면 경합이 중단됩니다. HASHBYTES
통화 속도를 줄이는 한 가지 방법은 통화 당 필요한 해싱 작업량을 늘리는 것입니다. 해싱 작업은 입력 문자열의 길이를 부분적으로 기반으로합니다. 응용 프로그램에서 본 확장 성 문제를 재현하기 위해 데모 데이터를 변경해야했습니다. 합리적인 최악의 시나리오는 21 인 테이블입니다.BIGINT
열. 테이블 정의는 하단의 코드에 포함되어 있습니다. Local Factors ™를 줄이기 위해 MAXDOP 1
상대적으로 작은 테이블에서 작동 하는 동시 쿼리를 사용하고 있습니다. 빠른 벤치 마크 코드가 맨 아래에 있습니다.
함수는 다른 해시 길이를 반환합니다. MD5
및 SpookyHash
모두 128 비트 해시하며, SHA256
256 비트 해시이다.
(결과 NVARCHAR
대 VARBINARY
변환 및 연결)
로 변환하고 연결하는 VARBINARY
것이 실제로보다 효율적이고 성능이 좋은지 확인하기 위해 저장 프로 시저 NVARCHAR
의 NVARCHAR
버전이 RUN_HASHBYTES_SHA2_256
동일한 템플릿에서 만들어졌습니다 (아래의 벤치마킹 코드 섹션의 "5 단계" 참조). 유일한 차이점은 다음과 같습니다.
- 저장 프로 시저 이름은
_NVC
BINARY(8)
대한 CAST
함수로 변화시켰다NVARCHAR(15)
0x7C
로 변경되었습니다 N'|'
를 야기하는:
CAST(FK1 AS NVARCHAR(15)) + N'|' +
대신에:
CAST(FK1 AS BINARY(8)) + 0x7C +
아래 표에는 1 분 동안 수행 된 해시 수가 포함되어 있습니다. 테스트는 아래에 언급 된 다른 테스트에 사용 된 것과 다른 서버에서 수행되었습니다.
╔════════════════╦══════════╦══════════════╗
║ Datatype ║ Test # ║ Total Hashes ║
╠════════════════╬══════════╬══════════════╣
║ NVARCHAR ║ 1 ║ 10200000 ║
║ NVARCHAR ║ 2 ║ 10300000 ║
║ NVARCHAR ║ AVERAGE ║ * 10250000 * ║
║ -------------- ║ -------- ║ ------------ ║
║ VARBINARY ║ 1 ║ 12500000 ║
║ VARBINARY ║ 2 ║ 12800000 ║
║ VARBINARY ║ AVERAGE ║ * 12650000 * ║
╚════════════════╩══════════╩══════════════╝
평균 만 살펴보면 다음으로 전환 할 때의 이점을 계산할 수 있습니다 VARBINARY
.
SELECT (12650000 - 10250000) AS [IncreaseAmount],
ROUND(((126500000 - 10250000) / 10250000) * 100.0, 3) AS [IncreasePercentage]
그 결과는 다음과 같습니다.
IncreaseAmount: 2400000.0
IncreasePercentage: 23.415
결과 (해시 알고리즘 및 구현)
아래 표에는 1 분 동안 수행 된 해시 수가 포함되어 있습니다. 예를 들어, CHECKSUM
84 개의 동시 쿼리를 사용 하면 시간이 다 떨어지기 전에 20 억 개 이상의 해시가 수행되었습니다.
╔════════════════════╦════════════╦════════════╦════════════╗
║ Function ║ 12 threads ║ 48 threads ║ 84 threads ║
╠════════════════════╬════════════╬════════════╬════════════╣
║ CHECKSUM ║ 281250000 ║ 1122440000 ║ 2040100000 ║
║ HASHBYTES MD5 ║ 75940000 ║ 106190000 ║ 112750000 ║
║ HASHBYTES SHA2_256 ║ 80210000 ║ 117080000 ║ 124790000 ║
║ CLR Spooky ║ 131250000 ║ 505700000 ║ 786150000 ║
║ CLR SpookyLOB ║ 17420000 ║ 27160000 ║ 31380000 ║
║ SQL# MD5 ║ 17080000 ║ 26450000 ║ 29080000 ║
║ SQL# SHA2_256 ║ 18370000 ║ 28860000 ║ 32590000 ║
║ SQL# MD5 8k ║ 24440000 ║ 30560000 ║ 32550000 ║
║ SQL# SHA2_256 8k ║ 87240000 ║ 159310000 ║ 155760000 ║
╚════════════════════╩════════════╩════════════╩════════════╝
스레드-초당 작업 수로 측정 된 동일한 숫자를 선호하는 경우 :
╔════════════════════╦════════════════════════════╦════════════════════════════╦════════════════════════════╗
║ Function ║ 12 threads per core-second ║ 48 threads per core-second ║ 84 threads per core-second ║
╠════════════════════╬════════════════════════════╬════════════════════════════╬════════════════════════════╣
║ CHECKSUM ║ 390625 ║ 389736 ║ 404782 ║
║ HASHBYTES MD5 ║ 105472 ║ 36872 ║ 22371 ║
║ HASHBYTES SHA2_256 ║ 111403 ║ 40653 ║ 24760 ║
║ CLR Spooky ║ 182292 ║ 175590 ║ 155982 ║
║ CLR SpookyLOB ║ 24194 ║ 9431 ║ 6226 ║
║ SQL# MD5 ║ 23722 ║ 9184 ║ 5770 ║
║ SQL# SHA2_256 ║ 25514 ║ 10021 ║ 6466 ║
║ SQL# MD5 8k ║ 33944 ║ 10611 ║ 6458 ║
║ SQL# SHA2_256 8k ║ 121167 ║ 55316 ║ 30905 ║
╚════════════════════╩════════════════════════════╩════════════════════════════╩════════════════════════════╝
모든 방법에 대한 몇 가지 간단한 생각 :
CHECKSUM
: 예상대로 매우 우수한 확장 성
HASHBYTES
: 확장 성 문제에는 호출 당 하나의 메모리 할당 및 OS에서 소비되는 대량의 CPU가 포함됩니다.
Spooky
: 놀랍도록 좋은 확장 성
Spooky LOB
: 스핀 록 SOS_SELIST_SIZED_SLOCK
이 제어에서 벗어납니다. 이것이 CLR 함수를 통해 LOB를 전달하는 일반적인 문제라고 생각하지만 확실하지 않습니다.
Util_HashBinary
: 같은 스핀 락에 부딪힌 것 같습니다. 나는 그것에 대해 할 수있는 일이 많지 않기 때문에 지금까지 이것을 보지 않았습니다.
Util_HashBinary 8k
: 매우 놀라운 결과, 여기서 무슨 일이 일어나고 있는지 잘 모르겠습니다.
더 작은 서버에서 테스트 한 최종 결과 :
╔═════════════════════════╦════════════════════════╦════════════════════════╗
║ Hash Algorithm ║ Hashes over 11 threads ║ Hashes over 44 threads ║
╠═════════════════════════╬════════════════════════╬════════════════════════╣
║ HASHBYTES SHA2_256 ║ 85220000 ║ 167050000 ║
║ SpookyHash ║ 101200000 ║ 239530000 ║
║ Util_HashSHA256Binary8k ║ 90590000 ║ 217170000 ║
║ SpookyHashLOB ║ 23490000 ║ 38370000 ║
║ Util_HashSHA256Binary ║ 23430000 ║ 36590000 ║
╚═════════════════════════╩════════════════════════╩════════════════════════╝
벤치마킹 코드
설정 1 : 테이블 및 데이터
DROP TABLE IF EXISTS dbo.HASH_SMALL;
CREATE TABLE dbo.HASH_SMALL (
ID BIGINT NOT NULL,
FK1 BIGINT NOT NULL,
FK2 BIGINT NOT NULL,
FK3 BIGINT NOT NULL,
FK4 BIGINT NOT NULL,
FK5 BIGINT NOT NULL,
FK6 BIGINT NOT NULL,
FK7 BIGINT NOT NULL,
FK8 BIGINT NOT NULL,
FK9 BIGINT NOT NULL,
FK10 BIGINT NOT NULL,
FK11 BIGINT NOT NULL,
FK12 BIGINT NOT NULL,
FK13 BIGINT NOT NULL,
FK14 BIGINT NOT NULL,
FK15 BIGINT NOT NULL,
FK16 BIGINT NOT NULL,
FK17 BIGINT NOT NULL,
FK18 BIGINT NOT NULL,
FK19 BIGINT NOT NULL,
FK20 BIGINT NOT NULL
);
INSERT INTO dbo.HASH_SMALL WITH (TABLOCK)
SELECT RN,
4000000 - RN, 4000000 - RN
,200000000 - RN, 200000000 - RN
, RN % 500000 , RN % 500000 , RN % 500000
, RN % 500000 , RN % 500000 , RN % 500000
, 100000 - RN % 100000, RN % 100000
, 100000 - RN % 100000, RN % 100000
, 100000 - RN % 100000, RN % 100000
, 100000 - RN % 100000, RN % 100000
, 100000 - RN % 100000, RN % 100000
FROM (
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
) q
OPTION (MAXDOP 1);
DROP TABLE IF EXISTS dbo.LOG_HASHES;
CREATE TABLE dbo.LOG_HASHES (
LOG_TIME DATETIME,
HASH_ALGORITHM INT,
SESSION_ID INT,
NUM_HASHES BIGINT
);
설정 2 : 마스터 실행 절차
GO
CREATE OR ALTER PROCEDURE dbo.RUN_HASHES_FOR_ONE_MINUTE (@HashAlgorithm INT)
AS
BEGIN
DECLARE @target_end_time DATETIME = DATEADD(MINUTE, 1, GETDATE()),
@query_execution_count INT = 0;
SET NOCOUNT ON;
DECLARE @ProcName NVARCHAR(261); -- schema_name + proc_name + '[].[]'
DECLARE @RowCount INT;
SELECT @RowCount = SUM(prtn.[row_count])
FROM sys.dm_db_partition_stats prtn
WHERE prtn.[object_id] = OBJECT_ID(N'dbo.HASH_SMALL')
AND prtn.[index_id] < 2;
-- Load assembly if not loaded to prevent load time from skewing results
DECLARE @OptionalInitSQL NVARCHAR(MAX);
SET @OptionalInitSQL = CASE @HashAlgorithm
WHEN 1 THEN N'SELECT @Dummy = dbo.SpookyHash(0x1234);'
WHEN 2 THEN N'' -- HASHBYTES
WHEN 3 THEN N'' -- HASHBYTES
WHEN 4 THEN N'' -- CHECKSUM
WHEN 5 THEN N'SELECT @Dummy = dbo.SpookyHashLOB(0x1234);'
WHEN 6 THEN N'SELECT @Dummy = SQL#.Util_HashBinary(N''MD5'', 0x1234);'
WHEN 7 THEN N'SELECT @Dummy = SQL#.Util_HashBinary(N''SHA256'', 0x1234);'
WHEN 8 THEN N'SELECT @Dummy = SQL#.Util_HashBinary8k(N''MD5'', 0x1234);'
WHEN 9 THEN N'SELECT @Dummy = SQL#.Util_HashBinary8k(N''SHA256'', 0x1234);'
/* -- BETA / non-public code
WHEN 10 THEN N'SELECT @Dummy = SQL#.Util_HashSHA256Binary8k(0x1234);'
WHEN 11 THEN N'SELECT @Dummy = SQL#.Util_HashSHA256Binary(0x1234);'
*/
END;
IF (RTRIM(@OptionalInitSQL) <> N'')
BEGIN
SET @OptionalInitSQL = N'
SET NOCOUNT ON;
DECLARE @Dummy VARBINARY(100);
' + @OptionalInitSQL;
RAISERROR(N'** Executing optional initialization code:', 10, 1) WITH NOWAIT;
RAISERROR(@OptionalInitSQL, 10, 1) WITH NOWAIT;
EXEC (@OptionalInitSQL);
RAISERROR(N'-------------------------------------------', 10, 1) WITH NOWAIT;
END;
SET @ProcName = CASE @HashAlgorithm
WHEN 1 THEN N'dbo.RUN_SpookyHash'
WHEN 2 THEN N'dbo.RUN_HASHBYTES_MD5'
WHEN 3 THEN N'dbo.RUN_HASHBYTES_SHA2_256'
WHEN 4 THEN N'dbo.RUN_CHECKSUM'
WHEN 5 THEN N'dbo.RUN_SpookyHashLOB'
WHEN 6 THEN N'dbo.RUN_SR_MD5'
WHEN 7 THEN N'dbo.RUN_SR_SHA256'
WHEN 8 THEN N'dbo.RUN_SR_MD5_8k'
WHEN 9 THEN N'dbo.RUN_SR_SHA256_8k'
/* -- BETA / non-public code
WHEN 10 THEN N'dbo.RUN_SR_SHA256_new'
WHEN 11 THEN N'dbo.RUN_SR_SHA256LOB_new'
*/
WHEN 13 THEN N'dbo.RUN_HASHBYTES_SHA2_256_NVC'
END;
RAISERROR(N'** Executing proc: %s', 10, 1, @ProcName) WITH NOWAIT;
WHILE GETDATE() < @target_end_time
BEGIN
EXEC @ProcName;
SET @query_execution_count = @query_execution_count + 1;
END;
INSERT INTO dbo.LOG_HASHES
VALUES (GETDATE(), @HashAlgorithm, @@SPID, @RowCount * @query_execution_count);
END;
GO
설정 3 : 충돌 감지 프로세서
GO
CREATE OR ALTER PROCEDURE dbo.VERIFY_NO_COLLISIONS (@HashAlgorithm INT)
AS
SET NOCOUNT ON;
DECLARE @RowCount INT;
SELECT @RowCount = SUM(prtn.[row_count])
FROM sys.dm_db_partition_stats prtn
WHERE prtn.[object_id] = OBJECT_ID(N'dbo.HASH_SMALL')
AND prtn.[index_id] < 2;
DECLARE @CollisionTestRows INT;
DECLARE @CollisionTestSQL NVARCHAR(MAX);
SET @CollisionTestSQL = N'
SELECT @RowsOut = COUNT(DISTINCT '
+ CASE @HashAlgorithm
WHEN 1 THEN N'dbo.SpookyHash('
WHEN 2 THEN N'HASHBYTES(''MD5'','
WHEN 3 THEN N'HASHBYTES(''SHA2_256'','
WHEN 4 THEN N'CHECKSUM('
WHEN 5 THEN N'dbo.SpookyHashLOB('
WHEN 6 THEN N'SQL#.Util_HashBinary(N''MD5'','
WHEN 7 THEN N'SQL#.Util_HashBinary(N''SHA256'','
WHEN 8 THEN N'SQL#.[Util_HashBinary8k](N''MD5'','
WHEN 9 THEN N'SQL#.[Util_HashBinary8k](N''SHA256'','
--/* -- BETA / non-public code
WHEN 10 THEN N'SQL#.[Util_HashSHA256Binary8k]('
WHEN 11 THEN N'SQL#.[Util_HashSHA256Binary]('
--*/
END
+ N'
CAST(FK1 AS BINARY(8)) + 0x7C +
CAST(FK2 AS BINARY(8)) + 0x7C +
CAST(FK3 AS BINARY(8)) + 0x7C +
CAST(FK4 AS BINARY(8)) + 0x7C +
CAST(FK5 AS BINARY(8)) + 0x7C +
CAST(FK6 AS BINARY(8)) + 0x7C +
CAST(FK7 AS BINARY(8)) + 0x7C +
CAST(FK8 AS BINARY(8)) + 0x7C +
CAST(FK9 AS BINARY(8)) + 0x7C +
CAST(FK10 AS BINARY(8)) + 0x7C +
CAST(FK11 AS BINARY(8)) + 0x7C +
CAST(FK12 AS BINARY(8)) + 0x7C +
CAST(FK13 AS BINARY(8)) + 0x7C +
CAST(FK14 AS BINARY(8)) + 0x7C +
CAST(FK15 AS BINARY(8)) + 0x7C +
CAST(FK16 AS BINARY(8)) + 0x7C +
CAST(FK17 AS BINARY(8)) + 0x7C +
CAST(FK18 AS BINARY(8)) + 0x7C +
CAST(FK19 AS BINARY(8)) + 0x7C +
CAST(FK20 AS BINARY(8)) ))
FROM dbo.HASH_SMALL;';
PRINT @CollisionTestSQL;
EXEC sp_executesql
@CollisionTestSQL,
N'@RowsOut INT OUTPUT',
@RowsOut = @CollisionTestRows OUTPUT;
IF (@CollisionTestRows <> @RowCount)
BEGIN
RAISERROR('Collisions for algorithm: %d!!! %d unique rows out of %d.',
16, 1, @HashAlgorithm, @CollisionTestRows, @RowCount);
END;
GO
설정 4 : 정리 (DROP 모든 테스트 프로세스)
DECLARE @SQL NVARCHAR(MAX) = N'';
SELECT @SQL += N'DROP PROCEDURE [dbo].' + QUOTENAME(sp.[name])
+ N';' + NCHAR(13) + NCHAR(10)
FROM sys.objects sp
WHERE sp.[name] LIKE N'RUN[_]%'
AND sp.[type_desc] = N'SQL_STORED_PROCEDURE'
AND sp.[name] <> N'RUN_HASHES_FOR_ONE_MINUTE'
PRINT @SQL;
EXEC (@SQL);
설정 5 : 테스트 프로세스 생성
SET NOCOUNT ON;
DECLARE @TestProcsToCreate TABLE
(
ProcName sysname NOT NULL,
CodeToExec NVARCHAR(261) NOT NULL
);
DECLARE @ProcName sysname,
@CodeToExec NVARCHAR(261);
INSERT INTO @TestProcsToCreate VALUES
(N'SpookyHash', N'dbo.SpookyHash('),
(N'HASHBYTES_MD5', N'HASHBYTES(''MD5'','),
(N'HASHBYTES_SHA2_256', N'HASHBYTES(''SHA2_256'','),
(N'CHECKSUM', N'CHECKSUM('),
(N'SpookyHashLOB', N'dbo.SpookyHashLOB('),
(N'SR_MD5', N'SQL#.Util_HashBinary(N''MD5'','),
(N'SR_SHA256', N'SQL#.Util_HashBinary(N''SHA256'','),
(N'SR_MD5_8k', N'SQL#.[Util_HashBinary8k](N''MD5'','),
(N'SR_SHA256_8k', N'SQL#.[Util_HashBinary8k](N''SHA256'',')
--/* -- BETA / non-public code
, (N'SR_SHA256_new', N'SQL#.[Util_HashSHA256Binary8k]('),
(N'SR_SHA256LOB_new', N'SQL#.[Util_HashSHA256Binary](');
--*/
DECLARE @ProcTemplate NVARCHAR(MAX),
@ProcToCreate NVARCHAR(MAX);
SET @ProcTemplate = N'
CREATE OR ALTER PROCEDURE dbo.RUN_{{ProcName}}
AS
BEGIN
DECLARE @dummy INT;
SET NOCOUNT ON;
SELECT @dummy = COUNT({{CodeToExec}}
CAST(FK1 AS BINARY(8)) + 0x7C +
CAST(FK2 AS BINARY(8)) + 0x7C +
CAST(FK3 AS BINARY(8)) + 0x7C +
CAST(FK4 AS BINARY(8)) + 0x7C +
CAST(FK5 AS BINARY(8)) + 0x7C +
CAST(FK6 AS BINARY(8)) + 0x7C +
CAST(FK7 AS BINARY(8)) + 0x7C +
CAST(FK8 AS BINARY(8)) + 0x7C +
CAST(FK9 AS BINARY(8)) + 0x7C +
CAST(FK10 AS BINARY(8)) + 0x7C +
CAST(FK11 AS BINARY(8)) + 0x7C +
CAST(FK12 AS BINARY(8)) + 0x7C +
CAST(FK13 AS BINARY(8)) + 0x7C +
CAST(FK14 AS BINARY(8)) + 0x7C +
CAST(FK15 AS BINARY(8)) + 0x7C +
CAST(FK16 AS BINARY(8)) + 0x7C +
CAST(FK17 AS BINARY(8)) + 0x7C +
CAST(FK18 AS BINARY(8)) + 0x7C +
CAST(FK19 AS BINARY(8)) + 0x7C +
CAST(FK20 AS BINARY(8))
)
)
FROM dbo.HASH_SMALL
OPTION (MAXDOP 1);
END;
';
DECLARE CreateProcsCurs CURSOR READ_ONLY FORWARD_ONLY LOCAL FAST_FORWARD
FOR SELECT [ProcName], [CodeToExec]
FROM @TestProcsToCreate;
OPEN [CreateProcsCurs];
FETCH NEXT
FROM [CreateProcsCurs]
INTO @ProcName, @CodeToExec;
WHILE (@@FETCH_STATUS = 0)
BEGIN
-- First: create VARBINARY version
SET @ProcToCreate = REPLACE(REPLACE(@ProcTemplate,
N'{{ProcName}}',
@ProcName),
N'{{CodeToExec}}',
@CodeToExec);
EXEC (@ProcToCreate);
-- Second: create NVARCHAR version (optional: built-ins only)
IF (CHARINDEX(N'.', @CodeToExec) = 0)
BEGIN
SET @ProcToCreate = REPLACE(REPLACE(REPLACE(@ProcToCreate,
N'dbo.RUN_' + @ProcName,
N'dbo.RUN_' + @ProcName + N'_NVC'),
N'BINARY(8)',
N'NVARCHAR(15)'),
N'0x7C',
N'N''|''');
EXEC (@ProcToCreate);
END;
FETCH NEXT
FROM [CreateProcsCurs]
INTO @ProcName, @CodeToExec;
END;
CLOSE [CreateProcsCurs];
DEALLOCATE [CreateProcsCurs];
테스트 1 : 충돌 확인
EXEC dbo.VERIFY_NO_COLLISIONS 1;
EXEC dbo.VERIFY_NO_COLLISIONS 2;
EXEC dbo.VERIFY_NO_COLLISIONS 3;
EXEC dbo.VERIFY_NO_COLLISIONS 4;
EXEC dbo.VERIFY_NO_COLLISIONS 5;
EXEC dbo.VERIFY_NO_COLLISIONS 6;
EXEC dbo.VERIFY_NO_COLLISIONS 7;
EXEC dbo.VERIFY_NO_COLLISIONS 8;
EXEC dbo.VERIFY_NO_COLLISIONS 9;
EXEC dbo.VERIFY_NO_COLLISIONS 10;
EXEC dbo.VERIFY_NO_COLLISIONS 11;
테스트 2 : 성능 테스트 실행
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 1;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 2;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 3; -- HASHBYTES('SHA2_256'
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 4;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 5;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 6;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 7;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 8;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 9;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 10;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 11;
EXEC dbo.RUN_HASHES_FOR_ONE_MINUTE 13; -- NVC version of #3
SELECT *
FROM dbo.LOG_HASHES
ORDER BY [LOG_TIME] DESC;
확인 문제 확인
단일 SQLCLR UDF의 성능 테스트에 중점을 두면서 초기에 논의 된 두 가지 문제는 테스트에 포함되지 않았지만 모든 요구 사항을 충족시키는 접근 방식을 결정하기 위해서는 이상적으로 조사해야합니다 .
- 함수는 각 쿼리마다 두 번 실행됩니다 (가져 오기 행에 대해 한 번, 현재 행에 대해 한 번). 지금까지의 테스트는 테스트 쿼리에서 UDF를 한 번만 참조했습니다. 이 요소는 옵션의 순위를 변경하지 않을 수 있지만 만일을 위해 무시해서는 안됩니다.
이후 삭제 된 의견에서 Paul White는 다음과 같이 언급했습니다.
HASHBYTES
CLR 스칼라 함수 로 대체 하는 한 가지 단점은 CLR 함수가 배치 모드를 사용할 수 없지만 HASHBYTES
할 수있는 것 같습니다. 성능 측면에서 중요 할 수 있습니다.
따라서 고려해야 할 사항이며 테스트가 필요합니다. SQLCLR 옵션이 내장에 비해 이점을 제공하지 않으면 솔로몬이 기존 해시 (최소한 가장 큰 테이블의 경우)를 관련 테이블에 캡처 HASHBYTES
한다는 제안 에 가중치를 추가합니다 .
Clear()
방법이 있지만 Spooky는 그다지 살펴 보지 않았습니다.