Wenn Sie eine Spalte haben, nach der Sie häufig eine Tabelle abfragen, sollten Sie normalerweise einen Index darauf kleben. Aber lohnt es sich auch, eine Tabelle nach dieser Spalte zu partitionieren, wenn alle möglichen Werte im Voraus bekannt sind? Angenommen , Sie haben eine Tabelle AUDIT
mit einer TenantId
Spalte, die nur Werte enthalten kann: 1, 2 .
Alle SELECT
Anweisungen hätten eine WHERE
Klausel mit einem TenantId
Parameter.
Wäre es also vorteilhaft, diese Tabelle nach TenantId zu partitionieren ? Wenn ja, würden Sie auch einen Index für die TenantId
Spalte erstellen ?
partition by list (TENANTID)
(
partition TENANT1 values (1),
partition TENANT2 values (2)
)
Ich habe ein kleines Experiment durchgeführt: 1 Million Datensätze mit zufällig generierter TenantId eingefügt, wodurch Folgendes erstellt wurde:
- 499652 Datensätze mit TenantId = 1
- 500348 Datensätze mit TenantId = 2
Hier sind die Abfragepläne für die Anweisung:
SELECT * FROM table1 WHERE TENANTID=2
Einfache Tabelle (keine Indizes, keine Partitionen) Bitmap-Index: Partitionen:
Übrigens, wenn ich sowohl den Index als auch die Partitionen habe, verwendet der Abfrageplan eine Partition und keinen Index, daher sieht der Plan genauso aus wie der oben gezeigte zweite.
Natürlich gewinnt die Partition, aber doch? Anscheinend ist die Kostenspalte in einem Ausführungsplan keine zuverlässige Methode, um die tatsächlichen Kosten einer Antwortzeit für SQL-Anweisungen zu beurteilen .
Also, was ist dann der beste Weg? Wie wählt man einen über den anderen?
quelle
Antworten:
Meine Meinung ist , dass in der Art , dass die Tabellenpartitionierung dargestellt kann nützlich sein.
Ihre Abfragen sind doppelt so schnell (wenn die Partitionen fast gleich sind), wenn sie vollständige Scans durchführen.
Wenn Ihre Abfragen einen anderen Ton von Filtern / Bedingungen haben und Indizes verwenden, ist die Partitionierung nicht sinnvoll, da die Ebene eines Index durch die Verdoppelung der Anzahl der Werte fast nicht beeinflusst wird.
UPDATE : Für den Test, den Sie durchgeführt haben (
SELECT * FROM table1 WHERE TENANTID=2
), ist es sicher, dass die Partitionierung am besten ist. Die Bitmap-Lösung muss den Index scannen und anschließend alle Tabellenblöcke scannen, die Zeilen mit enthaltentenantid=2
(sie weiß, was die Zeilen sind). Bei der Partitionierung wird jedoch nur die Partition der Tabelle mit tenantid = 2 gescannt. Sie sind phisisch getrennt vontenantid=1
.Also zwei Scans (Index-Scan + Tabellenscan) gegen einen Tabellenscan (der kleiner sein kann).
quelle
Wenn eine Spalte wie in Ihrem Fall nur wenige unterschiedliche Werte enthält, auch bekannt als niedrige Kardinalität, sollten Sie einen Bitmap-Index dafür erstellen. Wenn Sie häufig nach dieser Spalte abfragen, ist dies der Fall.
Weitere Informationen zu Oracle Bitmap-Indizes: http://www.dba-oracle.com/oracle_tips_bitmapped_indexes.htm
quelle