2017-11-14 3 views
0

비교적 일반적인 동적 쿼리 생성기를 작성하려고하고 일부 기술에 대해 궁금합니다. 20 ~ 100 개의 필터가있는 목록 페이지가 있습니다. 각 필터는 SqlGenerator 클래스가 INCLUDEd 및 WHERE 절이 필요한 전략을 SqlGenerator에 제공하도록 SQL 또는 "사용자 지정"을 만드는 방법을 알고 있다는 점에서 "표준"입니다.동적 SQL을 사용하여 필터링 절의 효율성

1.) 필터링 절을 수행하는 가장 좋은 방법은 무엇입니까?

가) 아주 간단까지 별도의 포함 된 각 필터를 유지하는 등 :

and exists (select 'x' from [company] c 
      where c.CompanyId = p.CompayId 
      and c.Rating >= 4) 
and exists (select 'x' from [company] c 
      where c.CompanyId = p.CompayId 
      and c.CityId = 5) 

B)를 하나에 통합은 존재하지만 /가 포함되어 관리 구축 할 필요가 없습니다.

and exists (
    select 'x' 
    from [company] c 
    where c.CompanyId = p.CompayId 
    and c.Rating >= 4 and c.CityId = 5) 

c) 동적으로 작성하기가 어렵지만 가장 깨끗한 것을 읽고 가장 효율적으로 실행되는 것처럼 보입니다.

select x, y, z 
from product p 
join company c on p.CompanyId = p.ProductId 
where c.Rating >= 4 and c.CityId = 5 

d) 조인에 where 절의 특정 부분을 두는 것이 더 효율적이라는 것을 알았습니다. 이 동적

select x, y, z 
from product p 
join company c on p.CompanyId = p.ProductId and c.Rating >= 4 and c.CityId = 5 

2) 이후, 나는 쿼리 캐시 계획 및 인덱스의 모든 혜택을 잃고 두려워 : 그것은이 작업을 수행하는 의미가 않습니다. 동일한 계획/색인을 사용하기 위해 최적화 된 것을 얻기 위해 항상 특정 조인과 절을 포함하는 것이 합리적입니까?

select x, y, z 
from product p 
join company c on p.CompanyId = p.ProductId 
where c.Rating >= ISNULL(@Rating, c.Rating) 
and c.CityId = ISNULL(@CityId, c.CityId) 

3.) 마지막으로, 조항의 순서를 수행하고 쿼리 계획 캐싱에 영향을 조인? 즉, AND 문의 순서를 바꾸면 두 가지 다른 계획입니까?

+0

참고 : 1c와 1d는 동일하지만 1a와 1b는 모두 서로 다르며 1c/1d와는 다릅니다. – ZLK

답변

2

검색어가 다른 것을합니다. 의미 론적으로 원하는 버전을 선택해야합니다.

(1a) 및 (1b)는 다른 일을합니다. 어떤 상황에서 그들은 동일한 일을합니다 - 특히 companyid이 테이블에서 유일하다면. 이 테이블이나 다른 테이블에 해당하는지 여부는 알 수 없습니다.

(1a)/(1b)와 (1c)는 다른 작업을 수행하며, 특히 companyId을 복제 할 수 있습니다.

(1c)/(1d) - 내부 조인을 위해 where에서 on으로 조건을 이동하는 데있어 차이점을 본 적이 없습니다. 물론 이것은 외부 조인에 차이를 만들 수 있습니다.

(2) 쿼리 캐시가 아닌 인덱스를 사용하는 것이 훨씬 더 중요합니다. 꽤 많은 여분의 데이터 페이지를 읽는 것은 대부분의 경우에 재 컴파일하는 것보다 오래 걸릴 것입니다.

(3) 복잡한 쿼리의 경우 조건과 테이블의 순서는 중요하지만 일반적으로 큰 문제는 아닙니다.

+0

감사합니다. 회사는 회사 ID가 고유합니다. 당신은 인덱스가 더 큰 관심사가되어야한다고 옳았습니다. 나는 그것에 대해 생각해 보았습니다. 그러나 질문을 쓸 때 제 마음을 몰래 따라 적절하게 업데이트했습니다. – TeamBrett

관련 문제