2010-08-06 4 views
2

범위 테이블의 :쿼리 성능이 여기에

CREATE TABLE Meetings 
(
    ID int PRIMRY KEY IDENTITY(1,1) 
    StartDate DateTime NOT NULL, 
    EndDate DateTime NULL, 
    Field1 varchar(50), 
    Field2 varchar(50), 
    Field3 varchar(50), 
    Field4 varchar(50) 
) 

000 여러 행이있다. 데이터 범위는 다양한 크기 일 수 있습니다 (몇 일에서 최대 50 년).

날짜 범위를 크게 할 수 있으므로, 테이블의 상당 부분이 리턴 될 수
DECLARE @ApplicableDate DateTime 

SELECT ID, StartDate, EndDate, Field1, Field2, Field3, Field4 
FROM Meetings 
WHERE StartDate <= @ApplicableDate AND 
    (EndDate is null || @ApplicableDate <= EndDate) 

(20 % 행의 50 %) :

여기 쿼리.

쿼리는 간단한 방식으로 원하는 행을 나타내지 만 성능은 상당히 나쁩니다. 어떤 인덱스를 추가하든 상관없이 클러스터 된 인덱스 스캔을 수행합니다. 나는 시도했다 :

  • 는 STARTDATE, 종료 날짜

가 어떻게이 쿼리의 성능을 향상시킬 수 있습니다 STARTDATE

?


내가 너무 this questionthis one에 대한 답변을 검토했습니다. 이러한 솔루션은 내 상황에서 도움이되지 않습니다. 쿼리를 동등 쿼리로 바꾸는 데 필요한 별도의 테이블을 만들어서 비즈니스 데이터에 신경 쓰고 싶지는 않습니다 (종료 날짜가 변경되면 어떻게됩니까? 아니면 null입니까?) 또는 공간 인덱스에 맞도록 데이터를 변형시켜야합니다. (그들은 행을 추가하지 않으며, 이상한 데이터 유형을 사용하지 않는 경우 특정) 아직

, 나는 데이터 구조에 가능한 수정에 열려있어 ..

+0

당신은 다음과 같이 시도 할 것입니다 :'@ApplicationDate와 ISNULL (enddate, '9999-12-31')'사이에 ISNULL을 사용하여 null enddates를 센티넬 값으로 변경하십시오. COALESCE는 옵션이지만 ISNULL은 더 빠른 경향이 있습니다. http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ISNULL_COALESCE –

답변

2

쿼리가 20 % -50 %의 반환하는 경우 레코드, 다음 스캔은 여러 번 최고의 옵션입니다. 인덱스가있는 경우 항상 인덱스의 데이터를 찾아 테이블에 레코드 주소를 포함시켜야합니다. 그런 다음이 레코드를 포함하는 페이지를 디스크에서 가져와 인덱스의 인접 레코드가 확산 될 위험이 있습니다 디스크 전체에.

  • 디스크 속도 문제인가 :

    정말 많은 기록과 성능이 나쁘다는 필요한 경우

    는, 어쩌면 다음 확인?

  • 네트워크 대역폭입니까?
  • RAM/캐시가 제한되어 있습니까?
3

구문에 대해 SQL Server를 사용하고 있다고 가정합니다.

ID의 기본 키를 클러스터되지 않은 인덱스로 만듭니다.

ID int PRIMARY KEY NONCLUSTERED IDENTITY(1,1), 

StartDate 열에 인덱스로 클러스터 된을 만듭니다.

CREATE CLUSTERED INDEX ix_Meetings_StartDate 
ON Meetings (StartDate) 

검색어를 그대로 사용하십시오. 데이터가 클러스터 된 PK와 비슷한 것으로 저장되어있을지라도 쿼리 엔진은 시작 날짜까지 데이터가 클러스터되어 있다는 것을 미리 알 수 있습니다.