Ich habe dies bereits für bestimmte Indizes getan, um häufig ausgeführte Abfragen zu unterstützen. Tatsächlich haben sie mehrere Clustered-Indizes erstellt: Wenn einer dieser Indizes zum Auffinden von Zeilen verwendet wird, ist keine zusätzliche Arbeit erforderlich, um den Rest der Daten im realen Clustered-Index (oder im Heap, wenn kein realer Clustered-Index vorhanden ist) nachzuschlagen. .
Ist das eine vernünftige Strategie?
Für einige Indizes, bei denen bestimmte Abfragemuster unterstützt werden müssen, sicherlich ja.
Aber um dies mit allen Indizes zu tun , würde ich genauso sicher nein sagen.
Es wird viel Platz verschwenden, wo es nicht wirklich benötigt wird, und Einfügungen / Aktualisierungen werden erheblich verlangsamt. Es kann so viele Leseabfragen verlangsamen, wie es auch hilft, da jede Indexseite weniger Datensätze enthält, sodass jede Abfrage, die zum Filtern auf einen Teil des Index verweisen muss, aber nicht alle anderen Spalten verwendet, auf mehr Seiten zugreifen muss. Dadurch wird Ihre Datenbank speicherhungriger: Diese Seiten müssen in den Pufferpool geladen werden, wodurch möglicherweise andere nützliche Seiten ausgeworfen werden, wenn der Arbeitsspeicher knapp ist. Wenn für diese Indizes eine Komprimierung verwendet wird, um die Auswirkungen auf die Speicher- und Speicheranforderungen zu verringern, werden stattdessen die CPUs zusätzlich belastet.
Der Zugriff erfolgt über ein ORM, das standardmäßig (aber nicht immer) alle Spalten abruft
Dies ist ein häufiges Muster mit schlecht optimierter Verwendung eines ORM (oder nur naiver ORMs). In diesen Fällen habe ich gesehen, dass der Indexberater von SQL Server (und ähnliche Tools von Drittanbietern) Indizes mit vielen INCLUDE
d-Spalten vorschlägt , daher stimme ich Ihrem zu Vorschlag, dass aus diesem Grund die Indizes auf diese Weise erstellt wurden.
Obwohl all diese Abfragen dadurch möglicherweise etwas schneller und einige erheblich schneller werden, vermute ich, dass in vielen Fällen der Nutzen so gering ist, dass er den zusätzlichen Speicherbedarf, den Ihr gemeinsamer Arbeitssatz, der Speicherplatz auf der Festplatte und der Festplatte benötigen, nicht wert ist die E / A zwischen Festplatte und Speicher.
Denken Sie auch daran, dass der ORM möglicherweise nicht alle Spalten aller Tabellen auswählt, die eine Abfrage berührt, sodass der Vorteil möglicherweise nur für das Hauptziel der aktuellen Anforderung gilt und die größeren Indizes die Abfrage möglicherweise benachteiligen, wenn andere Objekte zum Filtern verwendet werden aber keine Daten zurückgeben ( SELECT * FROM table1 WHERE id IN (SELECT someID FROM table2 WHERE someColumn='DesiredValue')
vielleicht).
Eine weitere Überlegung für den überschüssigen Speicherplatz, insbesondere wenn die Daten groß sind, besteht darin, dass er sich auf Ihre Sicherungsstrategie auswirkt: Speicher- und Übertragungskosten für diese Sicherungen, potenzielle Wiederherstellungszeiten usw.
sollten wir auf Unterschiede zwischen den beiden vorbereitet sein [on-prem & AzureSQL]
Im Allgemeinen denke ich, dass die Überlegungen hier in jedem Fall gleich sein werden, obwohl überschüssige Speicher- / E / A-Kosten, die durch die großen Indizes verursacht werden, in Azure möglicherweise direkter sichtbar sind, wo Sie die Serviceebene und damit die Infrastrukturkosten einfacher anpassen können als mit einem relativ festen Satz von Hardwareressourcen. Wenn Sie Standard- / Premium-Ebenen anstelle von vcore-basierten Preisen verwenden, sind Sie stärker von den Standard-E / A-Kosten betroffen, da Premium deutlich mehr E / A pro DTU enthält. Wenn Sie in Azure Sicherungen oder Redundanzen für mehrere Regionen oder andere nicht lokale Funktionen verwenden, entstehen möglicherweise Bandbreitenkosten, die mit dem zusätzlichen Speicherplatz verbunden sind, den ungewöhnlich große Indizes beanspruchen.
SELECT
ohne AngabeORDER BY
dieselben Zeilen wie zuvor zurückgegeben wurden, jedoch mit einer anderen willkürlichen Reihenfolge.