Wir haben ein Data Warehouse mit einer ziemlich großen Datensatzanzahl (10-20 Millionen Zeilen) und führen häufig Abfragen aus, die Datensätze zwischen bestimmten Datumsangaben oder Datensätze mit bestimmten Flags zählen, z
SELECT
f.IsFoo,
COUNT(*) AS WidgetCount
FROM Widgets AS w
JOIN Flags AS f
ON f.FlagId = w.FlagId
WHERE w.Date >= @startDate
GROUP BY f.IsFoo
Die Leistung ist nicht schlecht, kann aber relativ träge sein (vielleicht 10 Sekunden bei kaltem Cache).
Kürzlich entdeckte ich, dass ich GROUP BY
in indizierten Ansichten verwenden kann, und probierte etwas Ähnliches wie das Folgende aus
CREATE VIEW TestView
WITH SCHEMABINDING
AS
SELECT
Date,
FlagId,
COUNT_BIG(*) AS WidgetCount
FROM Widgets
GROUP BY Date, FlagId;
GO
CREATE UNIQUE CLUSTERED INDEX PK_TestView ON TestView
(
Date,
FlagId
);
Infolgedessen ist die Leistung meiner ersten Abfrage jetzt <100 ms und die resultierende Ansicht und der resultierende Index <100 KB (obwohl unsere Zeilenzahl groß ist, bedeutet der Bereich von Datums- und Flag-IDs, dass diese Ansicht nur 1000 bis 2000 Zeilen enthält).
Ich dachte, dass dies vielleicht die Leistung von Schreibvorgängen in die Widget-Tabelle verdreifachen würde, aber nein - die Leistung von Einfügungen und Aktualisierungen in diese Tabelle ist meines Erachtens ziemlich unbeeinträchtigt (und da es sich um ein Data Warehouse handelt, wird diese Tabelle nur selten aktualisiert sowieso)
Für mich ist das viel zu schön, um wahr zu sein - oder? Was muss ich beachten, wenn ich indizierte Ansichten auf diese Weise verwende?
SELECT
undCREATE VIEW
Skripte sind falsch, wie ich glaube, ist IhrCREATE INDEX
Skript.Antworten:
Wie Sie bereits bemerkt haben, materialisiert die Ansicht selbst nur eine geringe Anzahl von Zeilen. Selbst wenn Sie die gesamte Tabelle aktualisieren, ist der zusätzliche Aufwand für die Aktualisierung der Ansicht vernachlässigbar. Sie haben wahrscheinlich schon den größten Schmerz verspürt, den Sie spüren werden, als Sie die Ansicht erstellt haben. Die nächste Annäherung ist, wenn Sie der Basistabelle mehrere Millionen Zeilen mit einer Reihe neuer IDs hinzufügen, für die neue Zeilen in der Ansicht erforderlich sind.
Das ist nicht zu gut, um wahr zu sein. Sie verwenden indizierte Ansichten genau so, wie sie verwendet werden sollten - oder zumindest auf eine der effektivsten Arten: Sie bezahlen für zukünftige Abfrageaggregationen zum Zeitpunkt des Schreibens. Dies funktioniert am besten, wenn das Ergebnis viel kleiner als die Quelle ist und die Aggregationen natürlich häufiger angefordert werden, als die zugrunde liegenden Daten aktualisiert werden (in DW im Allgemeinen häufiger als in OLTP).
Leider halten viele Leute das Indizieren einer Ansicht für magisch - ein Index macht nicht alle Ansichten effizienter, insbesondere Ansichten, die einfach Tabellen verknüpfen und / oder die gleiche Anzahl von Zeilen wie die Quelle erzeugen (oder sogar multiplizieren). In diesen Fällen ist die E / A aus der Ansicht gleich oder sogar schlechter als die ursprüngliche Abfrage. Dies liegt nicht nur daran, dass es die gleichen oder mehr Zeilen gibt, sondern sie speichern und materialisieren häufig auch mehr Spalten. Das Materialisieren im Voraus bringt also keine Vorteile, da E / A, Netzwerk und Client-Verarbeitung / -Rendering - selbst bei SSDs - immer noch die primären Engpässe bei der Rückgabe großer Ergebnismengen an den Client darstellen. Die Einsparungen, die Sie durch das Vermeiden des Joins zur Laufzeit erzielen, sind im Vergleich zu allen anderen Ressourcen, die Sie noch verwenden, nicht messbar.
Achten Sie genau wie bei nicht gruppierten Indizes darauf, dass Sie nicht zu viel tun. Wenn Sie einer Tabelle 10 verschiedene indizierte Ansichten hinzufügen, wirkt sich dies stärker auf den Schreibteil Ihrer Workload aus, insbesondere wenn die Gruppierungsspalte (n) nicht im Clustering-Schlüssel enthalten sind.
Meine Güte, ich wollte über dieses Thema bloggen.
quelle
Aarons Antworten deckten diese Frage gut ab. Zwei Dinge, die hinzugefügt werden müssen:
Ich habe sowohl Aggregation als auch Join-Ansichten mit extremem Nutzen verwendet.
Alles in allem scheint Ihr Anwendungsfall ein perfekter Fall zu sein. Indizierte Ansichten sind eine Technik, die viel zu wenig genutzt wird.
quelle