이미 URL 컬럼에 인덱스를 가지고 있기 때문에, 내 생각은 SELECT (페이지 id를 얻을) 다음 존재하지 않는 경우 INSERT는 (새로운 URL)은 CPU를 최고로 만드는 원인입니다. 크롤러에 다중 스레드가있는 경우 tblPages에서 SQL의 동시성/잠금 메커니즘에 과세 할 수 있습니다.
특정 질문에 관해서는 해시 바이트 (md) 대신 CHECKSUM (crc)을 사용합니다. CHECKSUM은 빠르며, VARBINARY가 아닌 INT를 리턴하므로보다 쉽게 색인을 생성 할 수 있습니다.
그러나 CHECKSUM이 INT를 반환하기 때문에 정확하게 충돌이 발생하기 쉽기 때문에 URL을 AND 절로 검색해야합니다.
이제는 (PageUrl이 아닌) HashedUrl에만 열 색인을 넣으십시오. 충돌 가능성 때문에 색인이 고유하지 않아야합니다. 이렇게하면 테이블 행에 도달하기 시작할 때까지 가장 빠른 INSERT 및 SELECT가 제공됩니다.이 경우 INT CHECKSUM 충돌로 인덱싱되지 않은 PageUrl 열에 많은 부분 테이블 검색이 발생합니다. UPDATE
GO
/* NORMAL METHOD */
BEGIN
SET STATISTICS TIME ON
--
IF EXISTS(SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#Store1'))
BEGIN
DROP TABLE #Store1
END
-- Normal
CREATE TABLE #Store1 (Id INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED, Data VARCHAR(4000))
CREATE UNIQUE CLUSTERED INDEX CIX_STORE1_DATA ON #Store1(Data)
-- Help Create Data
DECLARE @Data TABLE(Data VARCHAR(4000))
INSERT INTO @Data(Data) VALUES ('red.'), ('YELLOW/'), ('green'), ('.BLUE'), ('/violet'), ('PURPLE-'), ('-orange')
-- The data set we'll use for testing
INSERT INTO @Data
SELECT a.Data + b.Data + c.Data + d.Data + e.Data + f.Data + g.Data
FROM @Data a, @Data b, @Data c, @Data d, @Data e, @Data f, @Data g
-- INSERTION TESTS
PRINT('INSERT INTO NORMAL')
INSERT INTO #Store1(Data)
SELECT Data FROM @Data
-- SELECTION TESTS
PRINT('SELECT FROM NORMAL')
SELECT TOP 5000 d.Data, (SELECT s.Id FROM #Store1 s WHERE s.Data = d.Data) FROM @Data d
--
SET STATISTICS TIME OFF
END
GO
/* USING YOUR OWN CHECKSUM/HASH */
BEGIN
SET STATISTICS TIME ON
--
IF EXISTS(SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#Store2'))
BEGIN
DROP TABLE #Store2
END
-- With Hash
CREATE TABLE #Store2 (Id INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED, Hsh INT, Data VARCHAR(4000))
CREATE CLUSTERED INDEX CIX_STORE2_CRC ON #Store2(Hsh)
-- Help Create Data
DECLARE @Data TABLE(Data VARCHAR(4000))
INSERT INTO @Data(Data) VALUES ('red.'), ('YELLOW/'), ('green'), ('.BLUE'), ('/violet'), ('PURPLE-'), ('-orange')
-- The data set we'll use for testing
INSERT INTO @Data
SELECT a.Data + b.Data + c.Data + d.Data + e.Data + f.Data + g.Data
FROM @Data a, @Data b, @Data c, @Data d, @Data e, @Data f, @Data g
-- INSERTION TESTS
PRINT('INSERT INTO CHECKSUM/HASH')
INSERT INTO #Store2(Hsh, Data)
SELECT CHECKSUM(Data), Data FROM @Data
-- SELECTION TESTS
PRINT('SELECT FROM CHECKSUM/HASH')
SELECT TOP 5000 d.Data, (SELECT s.Id FROM #Store2 s WHERE Hsh = CHECKSUM(d.Data) AND Data = d.Data) FROM @Data d
--
SET STATISTICS TIME OFF
END
결과를 사용하는 간단한 벤치 마크 코드 (짧은에서) 나의 방법은 빠른 (+ 30 %)을 달성 경과 "대"= 7339 밀리 경과 시간 "삽입의 시간 = 10318 ms "이지만 느린 (-30 %)"경과 된 시간 = 37 ms "와"경과 된 시간 = 28 ms "를 선택합니다.
또 다른 흥미로운 점은 너비 (HTTP 사양 ~ 4kb에 따라)가 900 바이트 (SQL 2008의 최대 허용 가능한 키 크기)를 초과하므로 "올바르게"URL VARCHAR 필드를 INDEX 할 수 없다는 것입니다. SQL에서는 경고 만 표시하지만 일부 INSERT/UPDATES는 잠재적으로 실패 할 수 있음을 경고합니다.
Warning! The maximum key length is 900 bytes. The index 'CIX_STORE1_DATA' has maximum length of 4000 bytes. For some combination of large values, the insert/update operation will fail.
가 나는 SQL 전문가가 아니에요 자체, 아마도 내 시험 방법은/가장 정확한 유용하지 않다, 그러나 주제는 '블랙 박스'대 관련되지 재치있는 사용자 엔드 최적화 매우 재미있다 .
URL 열에 색인이있는 것으로 의심됩니다. –
Eugen Rieck이 이미지를 보시기 바랍니다 : http://img62.imageshack.us/img62/589/exampleimage.png – MonsterMMORPG
이것은 이상하게 보입니다 - 질의 계획은 무시당하는 CPU, 일부 I/O 비용을 보여줍니다. 배고 있다). CPU가 사용자 영역 또는 커널을 사용합니까? –