1

실행 계획에 상당히 많은 병렬 테이블 스캔이 표시되므로 테이블 조회를 최적화하려고합니다. 표는 Opportunity이고 필터링 대상 열은 Name입니다.열 값이 'X'와 같지 않은 필터링 된 인덱스를 쓸 수 있습니까?

WHERE ([Name] NOT LIKE '%Supplement%'); 

나는이를 최적화 할 수있는 방법을 둘러보고 내가 필요한 인 필터링 된 인덱스를 건너 왔어요,하지만 한 돈 : 특히 나는 Name의 일환으로 "보충"이없는 모든 행을 원하는 LIKE 키워드를 좋아하는 것 같습니다. 이와 같은 필터링 된 색인을 생성하는 다른 방법이 있습니까?

테이블에 ~ 53k 개의 행이 있으며 서버에 직접 쿼리 할 때 데이터를 가져 오는 데 4 초가 걸리지 만 연결된 서버 (필요한 경우)로 쿼리하면 2 분이 걸립니다. 이 시간을 개선하기 위해 스크립트에서 쿼리를 이동하여 연결된 서버와 통신하고 원격 서버에서 뷰를 만들었습니다. 아직도 영원히 걸립니다.

는 여기에 지금까지 시도했다, 그러나 SSMS는 무효 말한다 : 어떤 제안에 미리

CREATE NONCLUSTERED INDEX [FX_NotSupplementOpportunities] 
    ON  [Opportunity]([Name]) 
    WHERE (([Name] NOT LIKE '%Supplement%') 
      AND ([Name] NOT LIKE '%Suplement%') 
      AND ([Name] NOT LIKE '%Supplament%') 
      AND ([Name] NOT LIKE '%Suppliment%')); 

감사합니다!

+0

SQL Server의 필터링 된 인덱스 조건에서는 'LIKE'을 사용할 수 없습니다. –

+0

다른 권장 사항이 있습니까? – Gup3rSuR4c

답변

3

당신은 일 것 Indexes on Computed Columns 예를 사용할 수 있습니다 :

CREATE TABLE [dbo].[MyTab](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Text] [varchar](max) NULL, 
    [OK] AS (case when NOT [text] like '%abc%' then (1) else (0) end) PERSISTED NOT NULL, 
CONSTRAINT [PK_MyTab] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
CREATE NONCLUSTERED INDEX [idx_OK] ON [dbo].[MyTab] 
(
    [OK] ASC 
)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 
+0

감사하지만, 받아들이 기는하지만 @ypercube의 답이 더 나은 것으로 보입니다. – bummi

2

불행하게도, 당신은 필터링 된 인덱스의 조건에 넣을 수 있습니다 무엇에 많은 제한 사항이 있습니다.

나는 MSDN에서 특정 아무것도하지만 브렌트 Ozar하여이 블로그 게시물을 찾을 수 없습니다 : 제한의 몇 가지 언급 What You Can (and Can’t) Do With Filtered Indexes : 당신은, ORBETWEEN, NOT IN, CASE 표현을 사용할 수 없습니다

.

그들은 단지 LIKE을 언급하지 않지만 간단한 테스트 (당신이했던 것처럼)도 당신이 할 수 없다는 것을 확인합니다. 허용 된 (a < 7)에 다시 쓸 수있는 (NOT (a >= 7))을 사용할 수 없습니다.

하나의 생각은 영속 열의 사례 표현을 사용한 다음 필터링 된 색인에서 지속 된 열을 사용하는 것입니다. 그러나 필터링 된 색인의 또 다른 제한 사항입니다.

그럼 어떻게하니? 유일하게 염두에 두어야 할 것은 영속 열을 생성하여 단순한 (필터링되지 않은) 색인에 사용하는 것입니다. 같은 뭔가 :

CREATE NONCLUSTERED INDEX FX_NotSupplementOpportunities 
    ON dbo.Opportunity 
     (special_condition, [Name]) ; 

및 쿼리의 (WHERE special_condition = 1)를 사용

ALTER TABLE dbo.Opportunity 
    ADD special_condition AS (CASE WHEN [Name] NOT LIKE '%Supplement%' 
            THEN 1 ELSE 0 END) 
     PERSISTED; 

그런 다음 열을 사용하여 인덱스를 추가 할 수 있습니다.

0

필자가 시도한 바에 가장 근접했기 때문에 @ bummi의 대답을 선택했지만 사용하지 않은 것은 아닙니다. 약간의 설명 ...

그래서 쿼리 검색을 더 빨리 수행하는 방법을 찾기 위해 수 시간이 지난 후에 실제로 여러 개의 병렬 처리 된 덩어리에서 두 개의 인덱스 검색으로 이뤄졌습니다. 나는 그것에 대해 매우 열광적 이었지만 결국에는 그것을 없애야했다.문제는 원격 데이터베이스가 실제로 Salesforce 데이터의 백업이라는 것입니다. 필자는 매우 복잡한 표와 열 변경을 통해 사전 및 사후 동기화를 수행해야만 올바르게 작동하지 않았고 각 동기화 (10 분마다)가 지워집니다.

나는 결국 데이터를 가져 와서 내 말에 다시 포맷하는 모든 것을하고있는 동안. 대신에 원격 서버의 뷰를 업데이트하고 가능한 한 많은 데이터를 포맷 한 다음 가져 오기로 결정했습니다. 그래서 저는 양면에서 SQL을 다시 작성하는 데 2 ​​시간을 보냈습니다. 그리고 ~ 25 분 정도의 스크립트를 3 분 미만으로 가져 와서 매우 만족스럽고 만족 스럽습니다.

결국 원격 서버의 쿼리 조회가 최적화되지 않았지만 여전히 빠릅니다. 대개 평균적으로 내가 만지고있는 대부분의 테이블에 최대 50,000 개의 행이 없으므로 ...