Wie kann eine Gewerkschaftsansicht effizienter ausgeführt werden?


8

Ich habe eine große Tabelle (zehn bis hundert Millionen Datensätze), die wir aus Leistungsgründen in aktive und archivierte Tabellen aufgeteilt haben, die eine direkte Feldzuordnung verwenden und jede Nacht einen Archivierungsprozess ausführen.

An mehreren Stellen in unserem Code müssen Abfragen ausgeführt werden, die die aktiven und archivierten Tabellen kombinieren und fast immer nach einem oder mehreren Feldern gefiltert werden (auf die wir offensichtlich in beiden Tabellen Indizes gesetzt haben). Der Einfachheit halber wäre es sinnvoll, eine Ansicht wie diese zu haben:

create view vMyTable_Combined as
select * from MyTable_Active
union all
select * from MyTable_Archive

Aber wenn ich eine Abfrage wie mache

select * from vMyTable_Combined where IndexedField = @val

Es wird die Vereinigung für alles von Active und Store durchführen, bevor nach gefiltert wird @val, was die Leistung beeinträchtigen wird.

Gibt es eine clevere Möglichkeit, die beiden Unterabfragen der Union so zu gestalten, dass sie jeden Filter anzeigen, @valbevor sie die Union erstellen?

Oder gibt es einen anderen Ansatz, den Sie vorschlagen würden, um das zu erreichen, was ich anstrebe, dh eine einfache und effiziente Methode, um den Gewerkschaftsdatensatz nach dem indizierten Feld zu filtern?

BEARBEITEN: Hier ist der Ausführungsplan (und Sie können die tatsächlichen Tabellennamen hier sehen):

Ausführungsplan

Seltsamerweise verwendet die aktive Tabelle tatsächlich den richtigen Index (plus eine RID-Suche?), Aber die Archivtabelle führt einen Tabellenscan durch!


Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
Paul White 9

Antworten:


8

Die Kommentare zu der Frage zeigen, dass das Problem darin besteht, dass die Testdatenbank, mit der das OP die Abfrage entwickelt hat, radikal andere Dateneigenschaften aufweist als die Produktionsdatenbank. Es hatte viel weniger Zeilen und das zum Filtern verwendete Feld war nicht selektiv genug.

Wenn die Anzahl der unterschiedlichen Werte in einer Spalte zu klein ist, ist der Index möglicherweise nicht ausreichend selektiv. In diesem Fall ist ein sequentieller Tabellenscan billiger als eine Indexsuch- / Zeilensuchoperation. In der Regel werden bei einem Tabellenscan häufig sequentielle E / A verwendet, die viel schneller sind als Lesevorgänge mit wahlfreiem Zugriff.

Wenn eine Abfrage mehr als nur ein paar Prozent der Zeilen zurückgibt, ist es häufig billiger, nur einen Tabellenscan durchzuführen als eine Indexsuche / Zeilensuche oder eine ähnliche Operation, bei der zufällige E / A häufig verwendet werden.


1

Nur um hinzuzufügen, was ich gefunden habe. Wenn Sie tun:

create view vMyTable_Combined as
select *, 1 AS [Active] from MyTable_Active
union all
select *, 0 AS [Active] from MyTable_Archive

Anschließend können Sie nach dem Feld [Aktiv] filtern und sicherstellen, dass der andere Teil nicht geladen ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.