2011-01-27 5 views
1

동일한 개념 값의 4 개 열인 큰 테이블 (100000 개 이상의 행)이 있습니다. SQLServer는 하나의 결과에 대해 여러 열을 인덱싱합니다.

는 기록이 이름 컬럼에 내가 연주하는 모든 대회에 대한 해당 테이블을 쿼리 할 때 A, B, C 및 D 그리고 A + B는 C + D.

대 재생 플레이어 간의 경쟁을 나타내는 말 'DOE %'또는 'DOE %'와 같은 열 B 또는 'DOE %'와 같은 열 C와 같은 열은 이름에 대한 4 열 값을 검사해야합니다.

... '또는 열 D'DOE % ') 및 기타 조건 ...

테이블이 거대하기 때문에, 나는 그 모든 4c에 색인을 붙이는 방법을 필요로합니다. olumns. ...

어떤을

나는 내가 그의 위치 A, B, C 또는 D 및 기본 테이블의 ROWID와 함께 각 선수의 이름을 저장하는 보조 테이블을 만들 수 있습니다 알고 있지만, 나는 더 나은 방법이 있어야한다 의심 SQLServer 전문가의 단서?

답변

3

각 열에 인덱스를 넣으면됩니다 (총 4 개의 인덱스).

그런 식으로 서버는 각 색인을 쿼리하고 조건에 따라 결과를 조합 할 수 있습니다. 이것은 광범위한 쿼리를 허용하며 여전히 상당히 빠릅니다.

내가 @ttoni 명시된대로 포함 열로 ID와 각 컬럼에 인덱스를 넣어 다음 ID에 포함 인덱스를 만들고 4 개 개의 열을 포함하고이 쿼리 실행됩니다
+0

나는 1 개의 쿼리 내에서 SQLServer가 오직 하나의 인덱스만을 선택하고 나머지는 부분 결과에서 처리되었다고 생각했다. - 어떤 경우에는 "OR"h 열 인덱스가 B, C 또는 D 선택에 도움이되지 않을 것이다. .. ??? –

+0

@ user512602 : SQL이 여러 인덱스를 참조하는 것을 막을 수있는 방법은 없습니다. 너무 비싸기 때문에 SQL은 일반적으로 그렇게하지 않습니다. 귀하의 경우에는 아마도 통계를 사용하여 어떤 색인이 가장 적은 결과를 제공하는지 결정한 다음 나머지 검색 용어를 해당 색인에 대한 술어로 추가하십시오. 그래도 당신의 경우에 충분해야합니다. 열의 내용과 검색어에 따라 하나의 열에 하나의 색인이 없어 질 수도 있지만 여기에서 말하기는 어렵습니다. – TToni

+0

YT 감사와 나쁜! 실행 계획을 보면 실제로 4 개의 인덱스가 모두 사용 된 것을 볼 수 있습니다. –

0

:

declare @string varchar(50) 
set @string='Karen' 

select 
    a.ID 
    A, 
    B, 
    C, 
    D 
from dbo.Players a 
    inner join 
    (
     select 
      ID 
     from dbo.Players 
     where A = @string 

     union all 
     select 
      ID 
     from dbo.Players 
     where B = @string 

     union all 
     select 
      ID 
     from dbo.Players 
     where C = @string 

     union all 
     select 
      ID 
     from dbo.Players 
     where D = @string 
    ) b 
     on a.ID=b.ID 

등호를 등호로 바꿀 수 있으며 변수의 끝에 백분율을 추가하면 그렇게하면 SQL Server에 대한 처리가 조금 더 필요합니다.

여기에 첫 번째 인덱스입니다 :

CREATE NONCLUSTERED INDEX [IDX_A] ON [dbo].[Players] 
(
    [A] ASC 
) 
INCLUDE ([ID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

여기 커버링 인덱스입니다 :

CREATE NONCLUSTERED INDEX [IDX_All] ON [dbo].[Players] 
(
    [ID] ASC 
) 
INCLUDE ([A], 
[B], 
[C], 
[D]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 
1
"I know I can create a secondary table storing each player name together 
with his position A, B, C or D and the main table's RowID, but I suspect 
there should be a better way..." 

을이 더 나은 방법입니다 관계형 데이터베이스에. 이유는 응용 프로그램 코드를 더 간단하게 만들고 DBA 함수를 더 간단하게 만듭니다.

1) playerID의 인덱스.

2) 쿼리? Select ... from playerGames where playerId = X

3) 현재 디자인은 위치 A, B, C 또는 D에있는 모든 플레이어를 찾는 간단한 쿼리 만 허용하며 이는 여전히 쉽습니다. 선택 ... from ... where 위치 = 'A'

이것은 데이터베이스 전문가가 정규화가 모호한 이론을 충족시키기 위해 수행하는 일이 아니라는 것을 종종 지적하지만 실제로는 정규화가 전체 시스템을 더 간단하게 만듭니다.

관련 문제