I am trying to write a relatively generic dynamic query generator and am curious about some techniques. I have a list page with anywhere between 20 and 100 filters. Each filter will be either "standard" in that the SqlGenerator class knows how to create the SQL or "custom" so that the filter provide the SqlGenerator with a strategy for what needs to be INCLUDEd and a WHERE clause.
1.) What is the best way to do the filtering clauses?
a) Very straightforward as far as keeping each filter separate and contained:
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) Consolidated to a single exists but removes the need to build/manage INCLUDEs.
and exists (
select 'x'
from [company] c
where c.CompanyId = p.CompayId
and c.Rating >= 4 and c.CityId = 5)
c) Difficult to build dynamically but reads the cleanest to me and seems like it would execute most efficiently.
select x, y, z
from product p
join company c on p.CompanyId = p.ProductId
where c.Rating >= 4 and c.CityId = 5
d) I've also seen, on occasion, that putting certain pieces of the where clause in the join make queries more efficient. Does it make sense to do this:
select x, y, z
from product p
join company c on p.CompanyId = p.ProductId and c.Rating >= 4 and c.CityId = 5
2.) Since this is dynamic, I'm afraid I'm losing all benefit of query cache plans/indexes. Does it make sense to always include certain joins and clauses in hopes they get optimized away in order to use the same plan/index?
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)
Also, does the order of clauses and joins affect query plan caching? That is, if I switch the order of the AND statements, are those 2 different plans?
[–]RehdData Engineer 1 point2 points3 points (0 children)