2010-06-16 3 views
0

내 직업은 SQL 서버 (MSSQL2005)를 많이 사용하는 하나의 유지 관리 응용 프로그램입니다.
지금까지 중간 서버는 TSQL 코드를 XML로 저장하고 저장된 procs를 사용하지 않고 동적 TSQL 쿼리를 보냅니다.
이러한 XML 쿼리를 변경할 수 있으므로 대부분의 쿼리를 저장된 procs로 마이그레이션하려고합니다.
질문 folowing된다TSQL 코드 최적화

Select 
    ..... 
from .... 
where .... 
and (a.vrsta_id = @vrsta_id or @vrsta_id = 0) 
and (a.podvrsta_id = @podvrsta_id or @podvrsta_id = 0) 
and (a.podgrupa_2 = @podgrupa2_id or @podgrupa2_id = 0) 
and (
(a.id in (select art_id from osobina_veze where podosobina_id in (select ado from dbo.fn_ado_param_int(@podosobina)) 
     group by art_id 
     having count(art_id)= @podosobina_count)) 
    or ('0' = @podosobina) 
) 

그들은 또한 같은이 곳의 다른 테이블에 조건 : 하나 개의 테이블에 대한 조건이

는 샘플 어디

내 쿼리의 대부분은 동일합니다.

코드를 어떻게 구성해야합니까?
적절한 방법은 무엇입니까?
내가 모든 쿼리에 사용할 테이블 값이있는 함수를 만들면
또는 #Temp 테이블과 간단한 내부 쿼리를 사용하여 proc을 실행할 때마다 내 쿼리에이 쿼리를 추가 할 수 있습니까? 또는 #temp를 테이블 반환 함수로 사용 하시겠습니까?
또는이 큰 where 절을 사용하여 모든 쿼리를 종료하고 해당 인덱스가 작업을 수행하기를 바랍니다.
또는 WITH (statement)을 사용하십시오.

답변

2

단일 쿼리에서 이와 같은 복잡한 검색을하는 것은 실제로 좋은 생각이 아닙니다.

나는 입력 조건 값에 대해 sql depeding을 생성하는 것을 선호한다. 이렇게하면 rsql 서버가 각 검색에 대해 더 나은 실행 계획을 쉽게 작성할 수 있습니다. 이 방법을 사용하면 쿼리에 대해 최적이 아닌 실행 계획을 가지고 있다고 확신 할 수 있습니다.

동적 SQL을 포함하므로 일반적인 경고가 적용된다는 것을 알고 있습니다.

2

하나의 테이블에서 값을 선택하고 반환 할 열을 선택하거나 해당 데이터에 조인 할 다른 테이블에서 두 가지 기능적 관심사가 있습니다. 하나의 테이블에서 필터링하는 항목 수가 많으면 중간 또는 작업 테이블에 선택한 값의 PK를 저장하려고합니다. 영구 테이블 인 경우 SessionId와 같은 다른 검색을 구분하거나 필터링 루틴에서 선택 루틴으로 전달하는 임의의 값으로 각 검색 결과 집합을 분리 할 수 ​​있습니다.

동적 루틴에서 필터링 루틴을 유지할 수있는 이유가 없습니다. 그러나 T-SQL에서 동적 SQL을 수행하려고하지는 않습니다. T-SQL은 문자열 조작에 끔찍합니다. 중간 계층에서 쿼리를 동적으로 작성하면 실제로 전달되지 않은 Where 절에서 요소를 제외 할 수 있습니다. 예를 들어, and (a.vrsta_id = @vrsta_id or @vrsta_id = 0) 대신에 @vrsta_id이 사실 0 일 때 a.vrsta_id = @vrsta_id 일 때이 줄을 모두 제외하고 @vrsta_id이 0이 아닌 경우에만이 줄을 제외 할 수 있습니다. 일반적으로 이러한 유형의 쿼리는 일련의 OR보다 더 잘 수행됩니다.

당신이 당신의 작업 테이블이 있으면, 당신의 선택 쿼리과 같이 보일 것이다 :이 경우

Select.. 
From WorkTable As W 
    Join ... 

Where SetId = 12345 
    And (OtherTable.Col = .... 

SetId는 필터링 루틴에서 생성 된 항목의 집합을 의미한다.

1

매개 변수를 가져와 일치하는 a.id 값의 테이블을 반환하는 테이블 값 함수를 만들 수 있습니다. 그런 다음 각 내장 프로 시저의 쿼리에 해당 함수를 내부 결합 할 수 있습니다. 예를 들면 : 당신은이 같은 곳 문에서 해당 기능을 사용할 수

select 
* 
from 
a 
inner join dbo.GetMatches(1,2,3,4) matches 
on a.id = matches.id 
inner join b on a.bID = b.bID -- example other table 

이 예제 쿼리에서 다음

create function dbo.GetMatches 
(
@vrsta_id int, 
@podvrsta_id int, 
@podgrupa2_id int, 
@podosobina_count int 
) 
returns table 
as 
return 
Select 
a.id 
from a 
where 
(a.vrsta_id = @vrsta_id or @vrsta_id = 0) 
and (a.podvrsta_id = @podvrsta_id or @podvrsta_id = 0) 
and (a.podgrupa_2 = @podgrupa2_id or @podgrupa2_id = 0) 
and (
(a.id in (select art_id from osobina_veze where podosobina_id in (select ado from dbo.fn_ado_param_int(@podosobina)) 
group by art_id 
having count(art_id)= @podosobina_count)) 
or ('0' = @podosobina) 
) 

...

where 
    a.id in (select id from dbo.GetMatches(1,2,3,4))