Eintritt gegen Ansichten, die in SQLServer mit seltsamen query optimizer-Verhalten
Ich habe einen komplexen Blick, den ich verwenden, ziehen Sie eine Liste der Primärschlüssel, die angeben, dass die Zeilen in einer Tabelle, die geändert wurden zwischen zwei zeitlichen Punkte.
Diese Ansicht hat zur Abfrage 13 verknüpften Tabellen und schau dir den changelog-Tabelle, um zu ermitteln, ob eine Entität ist "schmutzig" oder nicht.
Selbst mit all diesen Los, dabei eine einfache Abfrage:
select * from vwDirtyEntities;
Dauert nur 2 Sekunden.
Allerdings, wenn ich es ändern zu
select
e.Name
from
Entities e
inner join vwDirtyEntities de
on e.Entity_ID = de.Entity_ID
Diese dauert 1,5 Minuten.
Jedoch, wenn ich dies tun:
declare @dirtyEntities table
(
Entity_id uniqueidentifier;
)
insert into @dirtyEntities
select * from vwDirtyEntities;
select
e.Name
from
Entities e
inner join @dirtyEntities de
on e.Entity_ID = de.Entity_ID
Bekomme ich die gleiche Ergebnisse in nur 2 Sekunden.
Dies führt mich zu glauben, dass der SQLServer ist die Bewertung der anzeigen pro Zeile, wenn er kam, um Entitäten, anstatt die Erstellung einer Abfrage-plan, der beinhaltet die Teilnahme an der gemeinsamen inner join über die anderen Verknüpfungen in der Ansicht.
Beachten Sie, dass ich beitreten wollen, gegen die gesamte ResultSet von dieser Ansicht, als es filtert nur die Tasten, ich will intern.
Ich weiß, ich könnte es in einer materialisierten Sicht, aber das würde bedeuten, schema-Bindung, die Aussicht und die Abhängigkeiten und ich weiß nicht, wie die overhead-Pflege des index bewirken würde (Diese Ansicht wird nur abgefragt, für die Exporte, während es gibt weit mehr schreibt, um den zugrunde liegenden Tabellen).
So, abgesehen von einer table-variable zum Zwischenspeichern der Ergebnisse anzeigen, gibt es eine Möglichkeit zu sagen, die SQL Server-cache, um die Ansicht während der Auswertung der join? Ich habe versucht eine änderung der join-Reihenfolge (aus der Ansicht Auswählen und die Verknüpfung mit Entitäten), aber das machte keinen Unterschied.
Die Ansicht selbst ist auch sehr effizient, und es gibt keinen Raum zur Optimierung gibt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist nichts Magisches in den Blick. Es ist ein makro, das expandiert. Der Optimierer entscheidet, wenn er Kam, um erweitern Sie die Ansicht in der Haupt-Abfrage.
Werde ich die anderen Punkte in deinem Beitrag:
haben Sie ausgeschlossen eine indizierte Sicht. Eine Ansicht kann nur sein, eine diskrete Entität, wenn es indiziert ist
SQL Server wird nie ein RBAR-Abfrage alleine. Nur Entwickler schreiben Schleifen.
gibt es kein Konzept von Zwischenspeichern: jede Abfrage wird mit neuesten Daten, es sei denn, Sie verwenden Sie temporäre Tabellen
Sie darauf bestehen, mit der Aussicht, welche Sie sich entschieden haben, ist sehr effizient. Haben aber keine Ahnung, wie Ansichten behandelt, die der optimizer und es hat 13 Tabellen
SQL ist deklarativ: join-Reihenfolge meist keine Rolle spielt
Viele schwere DB-Entwickler verwenden nicht die Ansichten aufgrund von Einschränkungen wie diese: Sie sind nicht wiederverwendbar, da Sie Makros
Bearbeiten, eine andere Möglichkeit. Prädikat schieben auf SQL Server 2005. SQL Server kann nicht drücken Sie die JOIN-Bedingung "tiefer" in den Blick.