허용되는 시간 내에 실행되는 쿼리가 있지만 가능한 최대 성능을 짜고 싶습니다.
내가 개선하려는 작업은 노드 17의 계획 오른쪽에있는 "Index Seek"입니다.
적절한 색인을 추가했지만 해당 작업에 대한 추정치는 계산의 절반입니다.
인덱스를 변경하고 임시 테이블을 추가하고 쿼리를 다시 작성하는 방법을 찾았지만 올바른 견적을 얻기 위해 이보다 더 단순화 할 수는 없었습니다.
누구든지 내가 시도 할 수있는 것에 대한 제안이 있습니까?
전체 계획 및 세부 사항은 여기에서 확인할 수 있습니다 .
최신 정보:
질문의 초기 버전이 많은 혼란을 겪었다는 느낌이 들기 때문에 설명과 함께 원래 코드를 추가 할 것입니다.
create procedure [dbo].[someProcedure] @asType int, @customAttrValIds idlist readonly
as
begin
set nocount on;
declare @dist_ca_id int;
select *
into #temp
from @customAttrValIds
where id is not null;
select @dist_ca_id = count(distinct CustomAttrID)
from CustomAttributeValues c
inner join #temp a on c.Id = a.id;
select a.Id
, a.AssortmentId
from Assortments a
inner join AssortmentCustomAttributeValues acav
on a.Id = acav.Assortment_Id
inner join CustomAttributeValues cav
on cav.Id = acav.CustomAttributeValue_Id
where a.AssortmentType = @asType
and acav.CustomAttributeValue_Id in (select id from #temp)
group by a.AssortmentId
, a.Id
having count(distinct cav.CustomAttrID) = @dist_ca_id
option(recompile);
end
답변:
pasteThePlan 링크에서 초기 이름이 이상한 이유는 무엇입니까?
답변 : SQL Sentry Plan Explorer의 익명 계획을 사용했기 때문에.
왜
OPTION RECOMPILE?답변 : 매개 변수 스니핑을 피하기 위해 다시 컴파일 할 수 있기 때문에 (데이터가 왜곡 될 수 있습니다). 테스트를 마쳤으며를 사용하는 동안 Optimizer가 생성하는 계획에 만족합니다
OPTION RECOMPILE.WITH SCHEMABINDING?답변 : 정말로 피하고 싶고 인덱싱 된보기가있을 때만 사용하고 싶습니다. 어쨌든 이것은 시스템 기능 (
COUNT())이므로SCHEMABINDING여기서는 사용하지 마십시오 .
더 많은 가능한 질문에 대한 답변 :
왜 사용합니까
INSERT INTO #temp FROM @customAttrributeValues합니까?답변 : 쿼리에 연결된 변수를 사용할 때 변수 작업으로 인한 추정치는 항상 1임을 알았으므로 데이터를 임시 테이블에 넣는 것을 테스트 한 다음 Estimated 는 Actual Rows 와 같습니다. .
내가 왜 사용 했습니까
and acav.CustomAttributeValue_Id in (select id from #temp)했습니까?답변 : #temp에서 JOIN으로 바꿀 수 있었지만 개발자는 매우 혼란스러워
IN옵션을 제안했습니다 . 나는 대체로도 차이가있을 것이라고 생각하지 않으며 어느 쪽이든 문제가 없습니다.
select id from @customAttrValIds대신 실제 실행 계획에서 추정을 보았습니다. 대신 사용할 때 select id from #temp예상 행 수는 1변수 및 3#temp (실제 행 수와 일치)입니다. 그래서 내가로 교체 @했습니다 #. 그리고 나는 DO 그들이 TBL 변수를 사용 때의 추정은 항상 1이 될 것입니다 그리고 개선으로 더 좋은 평가들이 임시 테이블을 사용 얻을 수 있다고 말했다 (브렌트 O 또는 아론 버트 랜드에서) 이야기를 기억한다.






#temp창조와 사용이 성능의 문제가 아니라 이익이 될 것이라고 생각할 것이다. 색인화되지 않은 테이블에 저장하여 한 번만 사용합니다. 그 완전히 제거 (및 변경 시도in (select id from #temp)에exists. 하위 쿼리