Lohnt es sich, eine Tabelle in Oracle nach einem einzelnen Wert zu partitionieren?

7

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 AUDITmit einer TenantIdSpalte, die nur Werte enthalten kann: 1, 2 . Alle SELECT Anweisungen hätten eine WHEREKlausel mit einem TenantIdParameter.

Wäre es also vorteilhaft, diese Tabelle nach TenantId zu partitionieren ? Wenn ja, würden Sie auch einen Index für die TenantIdSpalte 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) Abfrageplan für einfache Tabellen Bitmap-Index: Bitmap-Index-Abfrageplan Partitionen: Partitionsabfrageplan

Ü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
Ich habe meine Antwort aktualisiert, um auf Ihr Update zu antworten.
Florin Ghita

Antworten:

4

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 enthalten tenantid=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 von tenantid=1.

Also zwei Scans (Index-Scan + Tabellenscan) gegen einen Tabellenscan (der kleiner sein kann).

Florin Ghita
quelle
3

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

Henrique Ordine
quelle
Vielen Dank, ich habe hier einen kleinen Test mit 1M Zeilen durchgeführt: 500348 mit TENANTID = 2, 499652 mit TENANTID = 1 zufällig verteilt und laut QUERY PLAN hat eine partitionierte Tabelle geringere Kosten (1112 gegenüber 1521) als eine mit Bitmap indizierte . Wie würden Sie es erklären?
11розный
Können Sie Ihre Anfrage hier posten?
Henrique Ordine
siehe die Bearbeitung bitte
Грозный
Ein Bitmap-Index ist möglicherweise keine gute Wahl, wenn die Tabelle häufig (und gleichzeitig) aktualisiert wird
a_horse_with_no_name
@Tsar, ich sehe, dass Sie zu dem Schluss gekommen sind, dass die Spalte Kosten, die Sie sich angesehen haben, sich als unzuverlässig herausgestellt hat. Ich muss Ihnen also wohl nichts mehr über Rowids erklären.
Henrique Ordine