Werden Ansichten optimiert, wenn ich ihnen eine WHERE-Klausel hinzufüge?

28

Macht es einen Unterschied, ob Sie eine Ansicht innerhalb oder außerhalb der Ansicht filtern?

Gibt es beispielsweise einen Unterschied zwischen diesen beiden Abfragen?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Oder

SELECT Id
FROM MyView
WHERE SomeColumn = 1

Und MyViewist definiert als

SELECT Id, SomeColumn
FROM MyTable

Und ist die Antwort anders, wenn sich die Quelltabelle auf einem Verbindungsserver befindet?

Ich frage, weil ich eine große Tabelle (44mil Zeilen) zweimal von einem Verbindungsserver abfragen und eine Zusammenfassung der Ergebnisse erhalten muss. Ich möchte wissen, ob ich zwei Ansichten erstellen soll, um auf die Daten zuzugreifen, eine für jede Abfrage, oder ob ich mit einer einzelnen Ansicht und einer WHEREKlausel davonkommen kann .

Rachel
quelle
1
Warum würden Sie überhaupt eine Ansicht verwenden, wenn Sie nur eine Tabelle darin haben?
HLGEM
3
@HLGEM Sicherheit?
JNK
2
@HLGEM Die Ansicht enthält tatsächlich mehrere Abfragen an mehrere Datenbanken auf verschiedenen Servern und verbindet sie alle durch ein UNION ALL. Es ist viel einfacher, eine Ansicht zu verwenden, als die UNION-Abfrage jedes Mal neu schreiben zu müssen, wenn ich die Daten benötige.
Rachel
1
@datagod Ich werde das im Hinterkopf behalten, danke :) In diesem Fall gibt es eine ziemlich kleine App, die Daten von einer Reihe von Servern sammelt, einige Berechnungen durchführt und eine Reihe von Berichten ausspuckt. Es hat eine eigene Datenbank, da einige der Berechnungen ziemlich ressourcenintensiv sind und ich sie von allem anderen trennen wollte.
Rachel am

Antworten:

12

Sie sollten absolut keinen Unterschied in den Plänen oder der Leistung zwischen diesen beiden Optionen sehen. Wenn die Ansicht abgefragt wird, wird sie zu einer Abfrage für die Basistabelle erweitert, was bedeutet, dass derselbe Such- oder Scanvorgang verwendet wird.

Abhängig vom Datentyp und der Selektivität von erhalten MyColumnSie möglicherweise eine bessere Leistung, wenn Sie einen gefilterten Index für die Basistabelle erstellen möchten (wenn Sie zu SQL Server 2008+ wechseln). Dies wird jedoch in der Ansicht nicht anders sein oder ohne.

Aaron Bertrand
quelle
3
Was ist mit dieser Frage , die fragt, warum eine Abfrage mit der whereKlausel außerhalb der Ansicht so viel länger dauert, als wenn sie in die Ansicht gestellt wird?
Rachel
1
Wenn Ansichten nicht für die Leistung sind, sind sie nur für die Struktur?
Profimedica
1
@profimedica- indizierte Ansichten können aus Leistungsgründen erstellt werden (z. B. um Zwischenergebnisse wie Aggregate zu speichern, anstatt sie zur Laufzeit zu berechnen). Wenn eine Ansicht nicht materialisiert wird, kann dies verschiedene Gründe haben: DRY (gemeinsamer Join oder Filter, der in vielen verschiedenen Abfragen ausgeführt wird), Sicherheit, Verschleierung, Vereinfachung des Schemas.
Aaron Bertrand
5

Hier ist nur ein kurzes Beispiel, das zeigt, dass es keinen Unterschied geben sollte. Die Datenbank ist die AdventureWorksDatenbank.

Zwei Ansichtsdefinitionen:

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

Hier wäre die erste Abfrage mit der WHEREKlausel, die in der Sichtdefinition enthalten ist:

select *
from person.vContactWhere

Hier ist der Ausführungsplan:

Bildbeschreibung hier eingeben

Und die zweite Abfrage mit der WHEREKlausel nicht in der Sichtdefinition, sondern in der SELECTAbfrage:

select *
from person.vContactNoWhere
where ContactID = 24

Hier ist der Ausführungsplan:

Bildbeschreibung hier eingeben

Wie Sie aus diesen Ausführungsplänen ersehen können, sind sie identisch mit identischen Ergebnissen. Ich kenne keine Situation, in der diese Art von Logik / Design zu unterschiedlichen Ergebnissen führen würde. Ich würde also gerne sagen, dass Sie in beiden Fällen in Sicherheit sind und Ihre persönlichen Vorlieben (oder Geschäftsprozesse) berücksichtigen.

Thomas Stringer
quelle
1
Was ist mit dieser Frage , die fragt, warum eine Abfrage mit der whereKlausel außerhalb der Ansicht so viel länger dauert, als wenn sie in die Ansicht gestellt wird?
Rachel
1
@ Rachel Ich denke, gbn hat es in seinem Beitrag und dem Artikel, auf den er verwies, ziemlich gut erklärt. Ich weiß nicht, wie ich es anders ausdrücken soll.
Thomas Stringer
Ich habe das verlinkt, weil in diesem Fall die Ausführungspläne nicht gleich waren, was sich von Ihrer Antwort unterscheidet.
Rachel
1
@ Rachel Das Problem in diesem Beispiel ist eine fehlende Transformationsregel . Dies gilt nicht nur für Ansichten, sondern auch für CTEs und andere Tabellenausdrücke. Im allgemeinen Fall ist es nicht gültig, das Prädikat in Tabellenausdrücke mit Rangfolgenfunktionen zu verschieben, da dies das Ergebnis ändert. Der Grund, warum es in diesem Fall gültig ist, liegt darin, dass die WhereKlausel mit der übereinstimmt PARTITION BY. SQL Server 2008 scheint eine neue Regel SelOnSeqPrjzu haben, um diesen speziellen Fall zu erkennen.
Martin Smith
2

Basierend auf dem, was ich lese , verwendet SQL eine Standardansicht wie eine Unterabfrage, um den Ausführungsplan zu bestimmen.

Also mit meiner Beispielabfrage,

SELECT Id
FROM MyView
WHERE SomeColumn = 1

wo MyViewist definiert als

SELECT Id, SomeColumn
FROM MyTable

Es sollte den gleichen Ausführungsplan wie generieren

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

Dieser Ausführungsplan kann sich jedoch von dem unterscheiden, mit dem er generiert wird

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Ich bin nicht sicher, ob diese Antwort für indizierte Ansichten gleich wäre

Rachel
quelle
Ich denke nicht, dass es sich um einen solchen expliziten Textersatz handelt.
Aaron Bertrand
@ AaronBertrand Sie könnten Recht haben. Ich habe ehrlich gesagt keine Ahnung ... ich lerne, während ich gehe :) Diese Annahme basierte auf anderen Dingen, die ich darüber gelesen habe, wie Ansichten wie Makros sind. Ich habe die Frage leicht bearbeitet, um anzugeben, dass ich mich auf Standardansichten und nicht auf indizierte Ansichten beziehe.
Rachel
@Rachel - Die Ersetzung erfolgt mit dem algebrisierten Baum nicht auf Textebene.
Martin Smith
@MartinSmith Hrrmm ist das nicht was ich gesagt habe? Dass die Ausführungspläne gleich sein sollten, nicht dass der Text gleich wäre? Ich bin nicht sicher, ob ich "Algebrized Tree" verstehe
Rachel
Es war nur eine Reaktion auf Ihren Kommentar zum Q selbst, der besagt, dass "der Text einer Ansicht in Ihre Suchanfrage eingefügt wird" und auf Aarons obigen Kommentar. Einige Informationen zum Parsen / Kompilieren finden Sie hier . Tatsächlich erwähnt Ihre Antwort auch die Textsubstitution. Ob dies eine Unterscheidung wert ist. Nicht sicher! Aber ich denke, es erklärt, warum sp_refreshviewes nötig ist, was das Konzept der Textsubstitution nicht würde.
Martin Smith