순차 및 비 순차 GUID를 비교하는 이 질문을 한 후 1) GUID 기본 키가 순차적으로 초기화 newsequentialid()
된 테이블 및 2) INT 기본 키가 순차적으로 초기화 된 테이블 의 INSERT 성능을 비교하려고했습니다 identity(1,1)
. 정수의 너비가 더 작기 때문에 후자가 가장 빠를 것으로 예상하고 순차 GUID보다 순차 정수를 생성하는 것이 더 단순 해 보입니다. 그러나 놀랍게도 정수 키가있는 테이블의 INSERT는 순차적 GUID 테이블보다 상당히 느 렸습니다.
테스트 실행의 평균 시간 사용량 (ms)이 표시됩니다.
NEWSEQUENTIALID() 1977
IDENTITY() 2223
누구든지 이것을 설명 할 수 있습니까?
다음 실험이 사용되었습니다.
SET NOCOUNT ON
CREATE TABLE TestGuid2 (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))
CREATE TABLE TestInt (Id Int NOT NULL identity(1,1) PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))
DECLARE @BatchCounter INT = 1
DECLARE @Numrows INT = 100000
WHILE (@BatchCounter <= 20)
BEGIN
BEGIN TRAN
DECLARE @LocalCounter INT = 0
WHILE (@LocalCounter <= @NumRows)
BEGIN
INSERT TestGuid2 (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
SET @LocalCounter +=1
END
SET @LocalCounter = 0
WHILE (@LocalCounter <= @NumRows)
BEGIN
INSERT TestInt (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
SET @LocalCounter +=1
END
SET @BatchCounter +=1
COMMIT
END
DBCC showcontig ('TestGuid2') WITH tableresults
DBCC showcontig ('TestInt') WITH tableresults
SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [NEWSEQUENTIALID()]
FROM TestGuid2
GROUP BY batchNumber
SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [IDENTITY()]
FROM TestInt
GROUP BY batchNumber
DROP TABLE TestGuid2
DROP TABLE TestInt
업데이트 : 아래의 Phil Sandler, Mitch Wheat 및 Martin의 예제와 같이 TEMP 테이블을 기반으로 삽입을 수행하도록 스크립트를 수정하면 IDENTITY가 더 빠릅니다. 그러나 이것이 행을 삽입하는 일반적인 방법은 아니며 처음에는 왜 실험이 잘못되었는지 이해하지 못합니다. 원래 예제에서 GETDATE ()를 생략하더라도 IDENTITY ()는 여전히 느립니다. 따라서 IDENTITY ()가 NEWSEQUENTIALID ()를 능가하는 유일한 방법은 임시 테이블에 삽입 할 행을 준비하고이 임시 테이블을 사용하여 일괄 삽입으로 많은 삽입을 수행하는 것 같습니다. 결론적으로, 우리가 현상에 대한 설명을 찾지 못했다고 생각하며 IDENTITY ()는 여전히 대부분의 실제 사용에서 느리게 보입니다. 누구든지 이것을 설명 할 수 있습니까?
IDENTITY
에는 테이블 잠금이 필요하지 않습니다. 개념적으로 MAX (id) + 1을 취할 것으로 예상 할 수 있지만 실제로 다음 값이 저장됩니다. 실제로 다음 GUID를 찾는 것보다 빠릅니다.