2017-11-14 3 views
0

Ich versuche, einen relativ generischen dynamischen Abfragegenerator zu schreiben und bin auf einige Techniken neugierig. Ich habe eine Listenseite mit zwischen 20 und 100 Filtern. Jeder Filter ist entweder "Standard", da die SqlGenerator-Klasse weiß, wie SQL oder "custom" erstellt wird, so dass der Filter dem SqlGenerator eine Strategie für das, was INCLUDE sein muss, und eine WHERE-Klausel zur Verfügung stellt.Effizienz von Filterklauseln mit dynamischem SQL

1.) Was ist der beste Weg, die Filterklauseln zu machen?

a) Sehr einfach so weit wie jeden Filter getrennt zu halten und enthalten:

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) Konzern zu einem einzigen besteht aber beseitigt die Notwendigkeit zu bauen/verwalten INCLUDEs.

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

c) Schwierige dynamisch zu bauen, sondern liest die sauberste mir und scheint, wie es am effizientesten durchführen würde.

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

d) Ich habe auch gelegentlich gesehen, dass die Inbetriebnahme bestimmte Teile der Where-Klausel in den Abfragen effizienter machen verbinden. Ist es sinnvoll, dies zu tun:

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

2.) Da diese dynamisch ist, ich fürchte, ich bin alle Nutzen der Abfrage-Cache Pläne und Indizes zu verlieren. Ist es sinnvoll, bestimmte Joins und Klauseln immer in die Hoffnung aufzunehmen, dass sie wegoptimiert werden, um den gleichen Plan/Index zu verwenden?

3.) Schließlich wirkt sich die Reihenfolge der Klauseln und Joins auf Abfrageplan-Caching aus? Das heißt, wenn ich die Reihenfolge der AND-Anweisungen ändere, sind diese 2 verschiedenen Pläne?

+0

Hinweis: 1c und 1d sind äquivalent, aber 1a und 1b unterscheiden sich voneinander und unterscheiden sich von 1c/1d. – ZLK

Antwort

2

Ihre Abfragen führen verschiedene Dinge aus. Sie sollten die Version wählen, die semantisch das tut, was Sie wollen.

(1a) und (1b), verschiedene Dinge tun. Unter bestimmten Umständen tun sie dasselbe - insbesondere wenn companyid in der Tabelle eindeutig ist. Ich weiß nicht, ob das für diese Tabelle oder für andere Tabellen gilt.

(1a)/(1b) und (1c) verschiedene Dinge tun, vor allem, wenn companyId dupliziert werden kann.

(1c)/(1d) - Ich habe noch nie einen Unterschied beim Verschieben einer Bedingung von der where zu einer on Klausel für eine innere Verbindung gesehen. Natürlich kann dies für einen äußeren Join einen Unterschied machen.

(2) Ich wäre viel mehr besorgt über die Verwendung von Indizes als Abfrage Caches. Das Lesen nur einiger zusätzlicher Datenseiten wird in den meisten Fällen länger dauern als das Neukompilieren.

(3) Für eine lange komplexe Abfrage kann die Reihenfolge der Bedingungen und Tabellen von Bedeutung sein, aber das ist im Allgemeinen kein Hauptproblem.

+0

Danke, Firma wird einzigartig auf Firmenidentifikation. Sie haben Recht, die Indizes sollten die größere Sorge sein, ich hatte darüber nachgedacht, aber es ist mir in den Sinn gekommen, als ich die Frage geschrieben und entsprechend aktualisiert habe, guter Punkt. – TeamBrett