2011-05-10 1 views
3

버전없이 + 대신 클러스터 된 인덱스 스캔의 키 조회를 추구 인덱스를 사용하도록 SQL Server를 가져 오기 : SQL 서버 2008 R2WITH (FORCESEEK)

데이터베이스 :의 AdventureWorks 2008R2에서 http://msftdbprodsamples.codeplex.com/releases/view/55926

검색어 :

SELECT TOP 10 
    * 
FROM 
    Person.Person --WITH (FORCESEEK) 
WHERE 
    LastName like 'Max%' 
    OR EXISTS (
     SELECT 
      1 
     FROM 
      Person.PersonPhone 
     WHERE 
      Person.PersonPhone.BusinessEntityID = Person.Person.BusinessEntityID 
      AND Person.PersonPhone.PhoneNumber LIKE '122%' 
    ) 
ORDER BY Person.Person.BusinessEntityID DESC 
어떤 쿼리 힌트없이


는, SQL 서버는 집중적 인 IO입니다 클러스터 된 인덱스 스캔을 사용합니다 :

어떤이,

Table 'Person'. Scan count 1, logical reads 59, physical reads 22, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'PersonPhone'. Scan count 1, logical reads 2, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 


내 질문은 다음 WITH (FORCESEEK) 쿼리 힌트로 97,045,943,210


, SQL Server가 인덱스를 선택하는 것입니다 빨리 완료하고 IO에 500 배 더 친절하다 + 키 조회를 추구 SQL Server에서 쿼리 힌트없이 더 나은 계획을 사용할 수있는 방법은 무엇입니까? 색인을 추가하는 것은 아마도? 또는 구성 매개 변수를 변경 하시겠습니까? 아니면 단서없는 SQL Server의 쿼리 최적화 프로그램입니까? 또한 최적화 오히려 인덱스보다 테이블이나 인덱스 스캔 작업을 수행하는 쿼리 검색으로 IN 또는 LIKE를 사용할 때 추구 될 수 있습니다

쿼리 최적화 규칙과 가난한 카디널리티 추정 : 여기

http://msdn.microsoft.com/en-us/library/bb510478.aspx에서 보석의 술어.

+1

SQL Server는 일부 쿼리를 자동으로 매개 변수화합니다. 그러나 구체적인 내용은 알지 못합니다. 그러나 모든 LIKE ... 값에 대해 위의 최적화를 시도 할 수 있으므로이 문제에 대한 나쁜 계획을 세우고 있습니다. 특정 검색. –

+0

@marc_s 질문을 읽으면 쿼리 힌트없이 쿼리 최적화 프로그램이 500 배 더 많은 IO를 필요로하는 계획을 선택한다는 것을 알 수 있습니다. 아마 그것은 내 디스크가 공회전하고 일하는 것을 갈망하고 있다는 것을 발견했을 것입니까? 그것은 좋은 이유 일 수 있습니다. 어쨌든 질문을 다시 읽었다 고 가정하면 쿼리 최적화 프로그램이 FORCESEEK없이 더 나은 계획을 선택할 수 있도록 도움을주는 방법을 묻고 있습니다. – sayap

+0

SQL Server가 하드웨어를 살펴보고 하드웨어가 현재 유휴 상태이므로 특정 계획이 좋은 것으로 결정할 것이라고 생각하지 않습니다. 계획 작성은 비용이 많이 듭니다. 자원 및 계획은 종종 재사용을 염두에두고 작성됩니다. –

답변

3

여기 FORCESEEK를 사용하지 않고 '알맞은'IO 수치를 보여주는 버전이 있습니다. 이 끔찍한 검색 쿼리가 '더 나은'기능을 수행한다는 것은 흥미 롭습니다.

부인은 ...이 '최대 %'와 '1백22퍼센트'더 나은 수행 할 수 있지만, 계획은 'M의 %'와 '%'재사용 또 다른 문제가되면 어떻게 수행 할 것

SELECT TOP 10 * 
FROM Person.Person P 
INNER JOIN (
SELECT BusinessEntityID 
FROM Person.Person --WITH (FORCESEEK) 
WHERE LastName like 'Max%'  

UNION 

SELECT BusinessEntityID 
FROM Person.Person --WITH (FORCESEEK) 
WHERE EXISTS (  SELECT   *  FROM   
    Person.PersonPhone  WHERE   Person.PersonPhone.BusinessEntityID = Person.Person.BusinessEntityID   AND Person.PersonPhone.PhoneNumber LIKE '122%' ) 
) NOTNICE 
ON NOTNICE.BusinessEntityID = P.BusinessEntityID 
ORDER BY P.BusinessEntityID DESC 
+0

감사합니다. 불행히도, 그것은 "ORM 친화적 인"것은 아닙니다. – sayap

+1

음, SQLAlchemy에는 "ORM과 호환되지 않습니다"와 같은 것이 없습니다. 나는 이것을 성공적으로 구현했다. 대답에 다시 한번 감사드립니다. – sayap