2010-07-12 4 views
3
declare @name varchar(156) 
set @name ='sara' 
--Query 1: 
SELECT [PNAME] FROM [tbltest] where [PNAME] like '%'[email protected]+'%' 

--Query 2: 
SELECT [PNAME] FROM [tbltest] where [PNAME] like '%sara%' 

[tbltest]의 [PNAME] 열에 없음 클러스터형 인덱스가 있다고 가정합니다. 쿼리, 실행 계획 표시 인덱스 쿼리 1을 검색하고 쿼리 2를 검색합니다. Excution Paln Show 인덱스 검색 두 쿼리 모두에 대해 첫 번째 쿼리에서 매개 변수를 사용하기 때문에 인덱스를 표시합니다. 그럼 내가 뭘? 두 쿼리에서 우리는 '%'를 다른 쪽에서 사용했으며이 상태에서 sql은 인덱스 을 고려하지 않지만 첫 번째 쿼리 실행 계획 인덱스에서 Seek? Sql 실행 계획에 동일한 입력에 대해 다른 결과가 표시됨

답변

0

테이블과 사용중인 인덱스에서 DBCC SHOW_STATISTICS를 수행하는 경우 출력의 첫 번째 행에서 "String Index = YES"를 찾습니다. SQL Server는 '% x'와 같은 쿼리를 만족시키기위한 일종의 추가 통계를 유지합니다.

첫 번째 쿼리에서는 계산 된 스칼라 값이 표시됩니다. LikeRangeStart ('%'+ @ name + '% '). Index Seek은 % sara %에 대한 인덱스 스캔과 대조되는 값에 대한 것입니다.

어떻게 작동합니까? 잘 모르겠습니다. SQL Server가 'sara'를 상수로 변환하고 쿼리를 내가 모르는 것과 똑같은 방식으로 수행 할만큼 충분히 똑똑하지 않은 이유는 무엇입니까? 그러나 나는 그렇게 생각합니다.

% sara %에 대해 전체 색인을 읽는 색인 스캔을 수행합니다. % + @ name + %에 대해 RangeStart/RangeEnd/RangeInfo 계산 된 값을 만들고이를 사용하여 추가 문자열 통계를 활용하여 색인 검색을 수행합니다.

0

나는 마이크가 당신이 색인을 치고 있는지 아닌지에 관해 올바른 길에 있다고 생각한다. 비용에 대한 후속 조치는 데이터가 테이블에서 어떻게 분산되는지에 대해 더 많은 이해가 필요합니다. 인덱스를 두 드릴 때 두 개의 디스크 읽기가 필요하기 때문에 비용이 많이 드는 경우를 보았습니다. 이유를 이해하려면 데이터가 색인 전체에 분산되는 방식, 한 페이지에 들어갈 레코드 수 및 캐싱 체계가 무엇인지를 알아야합니다.

선도적 인 %로 쿼리를 조정하는 것이 어려울 수도 있습니다. 데이터베이스는 색인 또는 표를 완전히 탐색하고 모든 노드에 "sara"가 포함 된 값을 찾아야합니다. 필요에 따라 전체 텍스트 검색을 고려할 수 있습니다 (예 : 응용 프로그램 사용자로부터 입력으로 제공되기 때문에이 쿼리에서 매개 변수 값이 사용됩니다).

1

쿼리 하나는 매개 변수 인 쿼리 2를 사용합니다.

상수 값을 변경하면 쿼리 2 계획이 다시 사용되지 않습니다.

계획 1에 대한 쿼리가 가능합니다. 이 경우 SQL Server는 계획을 재사용 할 수있는 옵션을 제공합니다.

깨어 있음 : 검색어는 이 아니며과 같습니다.

force parameterisation 인 경우 쿼리 1과 같이 두 쿼리를 실행해야합니다.하지만 시도하지 않았습니다.

관련 문제