2010-01-16 7 views
1

필자는 하루 종일 ~ 9 백만 행의 SQL Server 2000 db 테이블 최적화 작업을했습니다. 필자 만의 DB 경험은 수백 줄의 테이블을 가지고 있으므로 최적화를 다루지 않아도된다.SQL Server 2000 테이블 최적화

21 자리 숫자를 기준으로 선택 및 업데이트를 수행하고 있습니다.

인덱싱 된 char (21) 형식을 사용하면 쿼리에 2 초 이상 걸리고 SQL Server 프로세스에는 1.5GB의 RAM과 100 % CPU가 필요합니다.

인덱싱 된 bigint 형식을 사용하면 쿼리에 몇 밀리 초가 걸리고 프로세스에 약 100MB의 RAM이 필요합니다.

여기서 일어나는 일을 이해하고 싶습니다. 정상입니까? 아니면 성능 향상을 위해 char 유형을 인덱싱 할 수있는 구체적인 방법이 있습니까?

내 SQL의 Heres는 몇 가지 : C#을에서

CREATE TABLE data 
(
    tableID int NOT NULL IDENTITY PRIMARY KEY, 
    tag char(21) NOT NULL UNIQUE, 
    dataColumn1 datetime NULL, 
    dataColumn2 char(8) NULL, 
    lastModified datetime NOT NULL 
) 

매개 변수화 된 쿼리 : 어떤 도움

SELECT tag FROM data WHERE tag = @tag; 

감사합니다.

+0

이 모든 것이 정확한 표현이라고 가정하고 'tag'에 대한 인덱스가 있다고 가정 해 보겠습니다 ... 또 다른 제안은 각 쿼리를 테스트하기 전에 'DBCC FREEPROCCACHE' 및'DBCC DROPCLEANBUFFERS'를 시도해보십시오. 캐시 된 결과를 사용하고 있지 않은지 확인하십시오. 또한 실행 계획을 게시 할 수 있는지 확인하십시오 ('SET SHOWPLAN ON'). 계획에서 클러스터 된 인덱스 찾기 (또는 일반 인덱스 찾기)가 표시되고 검색, 책갈피 조회 또는 RID 조회가 없다면 속도를 향상시키기 위해 할 수있는 일은별로 없을 것입니다. – Aaronaught

답변

1

이것은 실제로 드문 일이 아니며 SQL은 문자보다 훨씬 나은 숫자를 처리합니다. bigInt 필드는 8 바이트를 사용하며 메모리 페이지에 깔끔하게 맞습니다. char 필드는 인덱스에 저장하기 위해 스토리지의 양을 거의 3 배로 늘리는 21 바이트를 사용합니다 ..

또 다른 고려 사항은 인덱스 클러스터입니까? 클러스터형 인덱스는 클러스터되지 않은 인덱스보다 훨씬 빠르게 수행됩니다. 고려해야 할 추가 요소가 많이 있습니다. 숫자가 더 잘 수행되고 색인에서 더 적은 공간을 사용한다는 단순한 일반 성명을 넘어서는 것입니다.

+0

느린 속도로 느려지지만 약간 느려질 것이라고 예상됩니다. 기본 키 인덱스와 해당 열의 인덱스가 있습니다. 하나의 행만 선택하기 때문에 둘 다 클러스터되지 않습니다. 내 이해 클러스터 된 인덱스 범위 쿼리에 대해서만 성능을 향상시킵니다. 많은 업데이트가 있으므로 클러스터 된 쿼리는 많은 디스크 I/O 성능에 영향을 줄 것이라고 생각합니다. – Matt

0

내 돈은 당신이 문자 열의 일부 기능, 즉 무엇인가 등에 쿼리하려는 가능성에있다 : 분명히

SELECT Column 
FROM Table 
WHERE UPPER(CharColumn) = 'ABC' 

난 그냥 추측하고있어,하지만 성능의 일반적인 원인이다 char/varchar/nvarchar 열 문제. 이와 같은 쿼리를 작성하는 경우 함수에서 열을 래핑하면 SQL Server에서 인덱스 검색을 수행 할 수 없습니다.

실제로 반환하는 행 수도 고려하십시오. 9 백만 행이 반드시 테이블에 있어야 할 필요는 없지만 결과 행에 10 만 행까지 있으면 엄청난 양입니다. 때로는 병목 현상이 모든 결과를 스트리밍하는 경우가 있습니다.

이 문제가 귀하의 문제를 설명하지 못하면 스키마, 인덱스 및 느리게 실행되는 쿼리에 대한 정보가 포함 된 게시물을 업데이트하는 것이 좋습니다. SQL Server 2000이 수년간 계속되고 있기는하지만 더 많은 최적화가 가능하므로 옵션이 제한적입니다. 당신의 tag 컬럼에 인덱스를 가지고 가정 당신이 게시 된 스키마를 기반으로


, 당신은 당신 WHERE 조건이에 대한 간단한 평등이라고 적용되지 않을 수 있습니다 tag 및 다른 열을 선택되지 않았는지 tag 열을 반환하고 반환되는 결과의 수가 비교적 적기 때문에 더 이상 최적화 할 수 있다고 생각하지 않습니다. 당신은 이것을 가능한 가장 단순한 경우로 축소 시켰습니다.

+0

기능을 사용하지 않고 열에서 직접 단일 행을 선택하고 업데이트합니다. 문제가되는 테이블에 두 개의 클러스터되지 않은 인덱스가 있습니다. 하나의 기본 키와 하나의 일반 인덱스가 21 자리 열에 있습니다. – Matt

+0

자세한 내용은 여전히 ​​도움이 될 것입니다. 인덱스가 커버 인덱스인지 여부를 알 수 없으며 때로 많은 인덱스 (또는 큰 인덱스)를 사용하면 업데이트 작업이 상당히 느려질 수 있습니다. 스키마, 인덱스 및 쿼리 (원하는 경우 익명화)에 대한 구체적인 정보를 제공 할 수 있다고 생각합니다. – Aaronaught

+0

또한 CHAR (21) 필드의 길이가 공백으로 채워져 있음을 유의하십시오. "ABC"가 포함 된 필드를 찾을 수 없습니다. "ABC ..."가 포함됩니다. ... "(여기서.는 공백을 나타냄) –

1

문자 비교는 다소 느립니다. 21 문자 문자열과 bigint (8 바이트) 사이의 물리적 인 차이는 말할 것도 없습니다. 인덱스는 char (21) 값의 각 바이트를 평가하고 문자의 정렬 순서를 결정한 다음 찾고있는 값의 일치하는 문자와 비교하는 방법을 결정해야하기 때문에 효율적으로 검색 할 수 없습니다 .

데이터 (인덱스 페이지 iirc를 포함하여 DBA가 아님)가 디스크 검색 순서이므로 거의 모든 쿼리에서 클러스터 된 인덱스가 더 잘 수행됩니다. 또는 적어도 그것에 더 가깝습니다.

+0

실제로 클러스터형 인덱스 * scan *은 일반 인덱스 스캔보다 느리게 수행됩니다. 그것이 내가 더 구체적인 것을 기대하고 있었던 이유 다. – Aaronaught