2009-08-24 1 views
15

수십 개의 서로 다른 시간에 테이블에 가입하고 있으며 매번 열 중 하나의 SUBSTRING 결과를 기반으로 조인 (또는 필터링)합니다 (문자열이지만 0으로 왼쪽 패딩 됨). 마지막 네 자릿수는 상관하지 않음). 따라서 SUBSTRING 자체는 인덱싱되지 않으므로이 열이 인덱싱되고 쿼리에서 인덱스를 사용하더라도 SQL Server는 조인 할 때마다 모든 행에 대해 SQL Server에서 계산해야하기 때문에 테이블 검색을 수행합니다.SQL Server - 계산 된 열의 인덱스?

이 과정의 속도를 높이는 방법에 대한 아이디어가 있습니다. 현재 테이블에 대한 뷰가 있습니다 (이는 테이블에 친숙한 이름을 지정하기 위해 "SELECT * FROM"입니다). 그리고 계산 된 뷰에 열을 추가 한 다음 인덱싱하는 것을 고려하고 있습니다. 나는 다른 제안에 열려 있, - 어떤 생각?

자세한 내용 : 먼저이 내용을 공유해야합니다. 테이블은 Google 결제 시스템에서 복제를 수신하므로 기본 테이블을 편집하여 계산 된 열을 추가하는 것은 옵션이 아닙니다. 계산 된 열은 테이블의 뷰에 추가되어야합니다. 또한 맨 앞의 0은 항상 0이되지는 않습니다. 그들은 때때로 내가 관심이없는 다른 데이터입니다. 실제 질문은 "입니다. VARCHAR 열의 중간에있는 데이터에 어떻게 참여할 수 있습니까? ? 인덱스의 사용 전체 텍스트 검색 "

내 예를 내가 단순화하고 있습니다 를 명확히하지만, 본질적으로,이 전 다음과 같은 값을 가진 열에서 값을 조회하기 위해 노력하고있어 가정 해 봅시다 :

00000MoreStuff 
00000Whatever 
19834212345 
Houses12345837443GGD 
00000023456MoreStuff 

행이 SUBSTRING (7,5) = "12345"인 행에 관심이 있습니다. 행 1-4가 필요하지만 행 5는 필요하지 않습니다. 제안하는 것은 addin입니다. g이 하위 문자열이 들어있는 "SELECT *"보기에 대한 열을 생성 한 다음이를 기반으로 색인을 생성합니다. 그게 더 합리적입니까?

+0

색인을 사용하려면 검색 조건에서 시작하도록 열을 변환해야합니다. 현재로서는 알고리즘이 너무 모호합니다. "항상 0이되는 것은 아니며"는 SQL Server에 설명하기가 어렵습니다. 'FULLTEXT' 색인은 단어 내의 접두사를 검색하는 데 사용할 수 있지만 (전체 열과 반대), 데이터를 단어로 나눠야합니다. 검색 알고리즘을보다 명확하게 정의 해 주시겠습니까? – Quassnoi

+0

색인 _SEEK_을 (를) 찾고 있다면 데이터가 충분히 선택 적인지 알아야합니다. 즉, 데이터베이스의 총 값 대 분산 값의 수의 비율은 얼마입니까? "크로스 오버 포인트"는 실제로 매우 낮습니다 (테이블의 너비에 따라 다름). 또한 인덱스에 선택한 열이 포함되어 있지 않으면 책갈피 조회에서 수행하는 읽기 횟수로 인해 SQL Server가 새로운 인덱스를 무시하게됩니다. 선택도/선택 목록에 대한 세부 정보를 제공 할 수 있습니까? – Anon246

답변

13

이 형식으로 필드가 가정 :

00Data0007 
000000Data0011 
0000Data0015 

, 당신은 다음을 수행 할 수 있습니다

  • 은 계산 열 만들기 : ndata AS RIGHT(REVERSE(data), LEN(data) - 4)

    이 변환됩니다 귀하의 항목을 다음에 입력하십시오 :

    ataD00 
    ataD000000 
    ataD0000 
    
  • 1,363,210 문자열 Data를 검색하여 해당 열

  • 문제에이 쿼리를 인덱스를 만듭니다

    SELECT * 
    FROM mytable 
    WHERE ndata LIKE N'ataD%' 
         AND SUBSTRING(ndata, LEN(N'ataD') + 1, LEN(ndata)) = REPLICATE('0', LEN(ndata) - LEN('ataD')) 
    

    첫 번째 조건은 거친 필터링을 위해 인덱스를 사용합니다.

    둘째는 (계산 된 열의 후행 문자가 된) 모든 선행 문자가 0에 불과하다는 것을 확인합니다.

성능 세부 사항에 대한 내 블로그에서이 항목을 참조하십시오 :

업데이트

당신이 당신의 스키마를 변경하지 않고 SUBSTRING에 인덱스를 원하는 경우, 보기 만들기는 옵션입니다.

CREATE VIEW v_substring75 
WITH SCHEMABINDING 
AS 
SELECT s.id, s.data, SUBSTRING(data, 7, 5) AS substring75 
FROM mytable 

CREATE UNIQUE CLUSTERED INDEX UX_substring75_substring_id ON (substring75, id) 

SELECT id, data 
FROM v_substring75 
WHERE substring75 = '12345' 
+0

이것이 제가 끝내게 될 것입니다. 나는 단지보기를 계획하고 그 다음에 나갈 것이 좋다. 포인터 주셔서 감사. – SqlRyan

1

LIKE 'something %'문과 관련하여 필터 기준을 다시 구사할 수 있습니까? (이것은 색인에 적용됩니다)

0

열을 두 열로 변경하십시오 - 사용자가 결합하는 데이터와 추가 4자를 변경하십시오. 열의 일부를 사용하면 본 것처럼 느려집니다.

6

계산 된 열을 테이블에 추가하고이 열에 색인을 만듭니다.

ALTER TABLE MyTable 
Add Column CodeHead As LEFT(Code,Len(Code)-4) 

그런 다음 색인을 생성하십시오.

CREATE INDEX CodeHeadIdx ON MyTable.CodeHead