다 열 복합 색인 사용 은 마이크로소프트 sql server 의 결함 을 우회 합 니 다.

5720 단어 다 열복합 색인
그러나 마이크로소프트 sql server 는 이러한 색인 을 처리 할 때 중요 한 결함 이 있 습 니 다.그것 은 색인 seek 로 컴 파일 해 야 할 작업 을 색인 스 캔 으로 컴 파일 하 는 것 입 니 다.이 로 인해 심각 한 성능 이 떨 어 질 수 있 습 니 다.예 를 들 어 문 제 를 설명 합 니 다.특정한 표 T 에 색인(city id,sentdate,userid)이 있다 고 가정 하면 현재 페이지 목록 기능 이 있 습 니 다.여러 열 이상 의 복합 색인 V0 에 대한 몇 개의 기록 을 얻 으 려 면 가장 간단 한 표 의 방식 으로 쓰 면 V>=V0 입 니 다.분해 하면:cityid>@cityid 0 or(cityid=@cityid 0 and(sentdate>@sentdate 0 or(sentdate=@sentdate 0 and userid>=@userid 0))입 니 다.상기 조 회 를 작성 할 때,sql server 가 위 를 V>=V0 형식의 경계 조건 으로 자동 으로 인식 하고 index seek 작업 을 통 해 이 조 회 를 실시 할 것 이 라 고 기대 할 것 입 니 다.그러나 마이크로소프트 의 sql server(2005 버 전)는 중요 한 결함(다른 sql server 가 어떻게 아직 모 르 는 지)이 있 습 니 다.이러한 sql 을 만 났 을 때 sql server 는 index scan 으로 실 시 됩 니 다.결 과 는 귀하 가 만 든 색인 이 전혀 사용 되 지 않 았 습 니 다.이 표 의 데이터 양 이 많 으 면 성능 이 매우 떨 어 집 니 다.이 문제 에 대해 나 는 마이크로소프트 관계자 에 게 제출 한 적 이 있다.그들 은 나 에 게 정식 사이트 에 가서 이 결함 을 제출 하 라 고 요구 했다.나 는 하기 가 귀찮다.그러나 이 결함 에 대해 서 는 돌아 갈 수 있 는 방법 이 있 습 니 다.위 에서 제시 한 조건 을 변형 시 키 면 sql server 는 저 성능 의 index scan 이 아 닌 index seek 로 돌아 갈 수 있 습 니 다.구체 적 으로 제 영어 원문 을 보 세 요.정 안 되 는 것 은 흑체 부분 을 보 세 요.):The seek predicate of the form"x>bookmarkof_x" is needed in paging related query. The compiler has no difficulty to parse it correctly if x is a single column index, or two columns index, however, if x is a three columns index or more, then the compiler will have a hard time to recognize it. This failure will result in that the seek predicate ended up in residue predicate, which results in a much worse execution plan. To illustrate the point, take a example, Create table A( a int, b int, c int, d float, primary key (a, b, c)) now check the plan for the query: select c, d from A where (a> 111 or a= 111 and (b > 222 or b = 222 and c > 333)) you can see a table scan op is used, and the Where clause ended up in residue predicate. However, if you rewrite the query in an equivalent form: select c, d from A where a> 111 or a= 111 and b > 222 or a= 111 and b= 222 and c >333 Then the compiler can choose an index seek op, which is desired. The problem is,the compiler should be able to recognize the first form of seek predicate on multiple columns index,it saves the user from having to pay extra time to figure out a get-around,not to mention the first form is a more efficient form of same expression.위의 문 제 는 부분 적 으로 돌 아 갔 지만 돌 이 킬 수 없 을 때 도 있 습 니 다.이 어 다음 단락 을 살 펴 보 겠 습 니 다.sql 서버 에 벡터 북 마크 나 벡터 비교 또는 호출 하고 싶 은 것 이 부족 한 것 같 습 니 다.해결 방법 은 완벽 한 해결 방법 이 아 닙 니 다.sql 서버 가 벡터 북 마크 의 개념 을 이해 하려 면, then the following two would be the same in execution plan and performance: 1. select top(n) * from A where vectorIndex >= @vectorIndex 2. select * from A where vectorIndex >= @vectorIndex and vectorIndex <=@vectorIndexEnd -- @vectorIndexEnd corresponds to the last row of 1. However, test has shown that, the second statement takes far more time than the first statement, and sql server actually only seek to the begining of the vector range and scan to the end of the whole Index, instead of stop at the end of the vector range. Not only sql server compile badly when the vector bookmark has 3 columns, test has shown that even with as few as 2 columns,sql serer still can not correctly recognize this is actually a vector range,example:3.selecttop(100)a,b,c,d from A where a>60 or a=60 and b>20 4.selecta,b,c,d from A where(a>60 or a=60 and b>20)과(a<60 or a=60 and b<=21)위의 두 조 회 는 실질 적 으로 같 고(표 의 데이터 가 딱 이와 같다)동종 업계 의 결과 집합 을 제시 합 니 다.그러나 3 대 4 의 속도 가 훨씬 빠 릅 니 다.execution plan 을 보면 3 이 4 보다 빨 라 야 한 다 는 것 을 증명 합 니 다.즉,색인 vectorIndex 가 두 열 만 포함 되 어 있 는 상황 에서 도 sql server 는 범위 표현 식@vectorIndex 0
CREATE TABLE [dbo].[A](
[a] [int] NOT NULL,
[b] [int] NOT NULL,
[c] [int] NOT NULL,
[d] [float] NULL,
PRIMARY KEY CLUSTERED ([a] ASC, [b] ASC, [c] ASC)
)
declare @a int, @b int, @c int
set @a =1
while @a <= 100
begin
set @b = 1
begin tran
while @b <= 100
begin
set @c = 1
while @c <= 100
begin
INSERT INTO A (a, b, c, d)
VALUES (@a,@b,@c,@a+@b+@c)
set @c = @c + 1
end
set @b = @b + 1
end
commit
set @a = @a + 1
end
SET STATISTICS PROFILE ON
SET STATISTICS time ON
SET STATISTICS io ON

select top (10) a, b, c, d from A where (a> 60 or a= 60 and
(b > 20 or b = 20 and c >= 31))
select a, b, c, d from A where (a> 60 or a= 60 and
(b > 20 or b = 20 and c >= 31)) and (a< 60 or a= 60 and
(b < 20 or b = 20 and c <= 40))

select top (10) a, b, c, d from A where a> 60 or a= 60 and b > 20 or a= 60 and b= 20 and c >= 31
select a, b, c, d from A where (a> 60 or a= 60 and b > 20 or a= 60 and b= 20 and c >= 31) and
(a< 60 or a= 60 and b < 20 or a= 60 and b= 20 and c <= 40)
select top (100) a, b, c, d from A where a> 60 or a= 60 and b > 20
select a, b, c, d from A where (a> 60 or a= 60 and b > 20) and (a< 60 or a= 60 and b <= 21)
select top (100) a, b, c, d from A where a> 60 or a= 60 and b > 20
select a, b, c, d from A where (a> 60 or a= 60 and b > 20) and (a< 60 or a= 60 and b <= 21)

좋은 웹페이지 즐겨찾기