Performance by Example: Single Column Index versus Multicolumn Index

Anwendungsbeispiel

In einer Applikation werden Daten in einer großen Tabelle gesucht – allerdings dauert die Abfragen sehr lange. Nehmen wir als Beispiel an, die Tabelle hieße OFFER (Angebot). Sie hat ca. 20 Spalten, unter anderem die Spalten DIM_CATEGORY_KEY und OFFER_TIME. Der Entwickler hat auf den Spalten der Tabelle jeweils einen einspaltigen Index angelegt.

Folgende, vereinfachte Abfrage kommt zur Anwendung:

SELECT *
  FROM OFFER
 WHERE DIM_CATEGORY_KEY IN (27,28)
   AND OFFER_TIME BETWEEN TO_DATE('2023-01-01', 'YYYY-MM-DD') 
                      AND TO_DATE('2023-01-31', 'YYYY-MM-DD');

Betrachten wir dazu den Ausführungsplan:

-----------------------------------------------------------------------...
| Id  | Operation                             | Name          | Rows  |...
-----------------------------------------------------------------------...
|   0 | SELECT STATEMENT                      |               |   249 |...
|   1 |  INLIST ITERATOR                      |               |       |...
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED | OFFER         |   249 |...
|*  3 |    INDEX RANGE SCAN                   | OFFER_CAT_IDX | 14210 |...
-----------------------------------------------------------------------...

Wie man sieht, wurde einer der beiden Indizes herangezogen, nämlich der auf der Spalte DIM_CATEGORY_KEY. Da in der Datenbank aber mehrere Jahre an Daten vorhanden sind, müssen in Summe rund 14.210 Datensätze gelesen werden, um die Daten aus dem gewünschten Zeitraum (OFFER_TIME) zu ermitteln.

Was passiert, wenn wir einen Index anlegen, der beide Spalte auf einmal enthält?

CREATE INDEX OFFER_MULTI_IDX1 ON OFFER (DIM_CATEGORY_KEY,OFFER_TIME);

Was Ändert sich am Ausführungsplan?

---------------------------------------------------------------------------...
| Id  | Operation                             | Name              | Rows  |...
---------------------------------------------------------------------------...
|   0 | SELECT STATEMENT                      |                   |   249 |...
|   1 |  INLIST ITERATOR                      |                   |       |...
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED | OFFER             |   249 |...
|*  3 |    INDEX RANGE SCAN                   | OFFER_MULTI_IDX1  |   249 |...
---------------------------------------------------------------------------...

Ja, der neue Index wird verwendet und es werden über den Index nur noch jene 249 Datensätze gefunden,
die auf Grund der WHERE Bedingung benötigt werden.

Bedeutet das, dass jetzt für jede Abfrage ein passender Index angelegt werden soll?

Ein klares „JEIN“. Es hängt stark von der Art der Applikation und der Datennutzung ab!

  • Bei OLTP (großteils interaktive Applikationen) führen zu viele Indizes dazu, dass DML (Datenänderungen) zu stark gebremst werden.
  • Bei DWH/DSS/DataLake Anwendungen, bei denen der Großteil der Verarbeitung aus Abfragen besteht, sind passende Indizes sehr wichtig.

Zusammenfassung

Die richtige und sinnvolle Indizierung hat dramatische Auswirkungen auf die Applikationsperformance. Es ist wichtig, das richtige Augenmaß beim Anlegen der Indizes zu bewahren.

Mehr zu dem Thema gibt es hier

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

This site uses Akismet to reduce spam. Learn how your comment data is processed.