mehrspaltiger Index: Reihenfolge Spalten im Index (Kardinalität)

nowonowo

Benutzer
Beiträge
16
Hallo zusammen,

ich weiß, dass die Reihenfolge der Spalten im mehrspaltigen Index der Reihenfolge der Abfrage im Where-Teil entsprechen muss.

Da der WHERE-Teil in Verbindung mit der Reihenfolge der Spalten im mehrspaltigen Index umgestellt werden kann würde es mich interessieren, welche Reihenfolge man am besten verwenden soll.

Es gibt ja die Angabe "Kardinalität", welche angibt, wieviele Elemente eine Spalte im Index enthält.
Nun habe ich entdeckt, dass die Kardinalitäten je nach Anordnung der Spalten im Index anders angegeben werden.
Deshalb denke ich, dass die Reihenfolge im Index wohl eine große Rolle spielen wird?
 
Werbung:
Ja, das ist mir klar :)
Angenommen in der Where-Condition werden 4 Spalten benannt, welche dann natürlich auch im Index in der selben Reihenfolge enthalten sind.
Nun gibt es aber die Möglichkeit, diese 4 Spalten sowohl in der Where-Condition als auch im Index in der Reihenfolge zu ändern.
Im Index ergibt sich dann eine andere Kardinalität. Spielt das eine Rolle (Geschwindigkeit der SELECT-Abfrage)?

Zur Verdeutlichung:

Index.png


-> Welcher Index ist besser (Where-Condition muss natürlich zum Index passen)?
 
Zuletzt bearbeitet:
Im Index würde ich generell die selektivsten Spalten zuerst nennen, diese kommen (hoffentlich / wahrscheinlich) auch im Select immer vor. Ansonsten spielt die Reihenfolge im Select (zumindest in PG) keine Rolle:

Code:
test=# create table blafasel(c1 int, c2 int, c3 int, c4 int);
CREATE TABLE
test=*# create index idx_blafasel on blafasel(c1, c2, c3, c4);
CREATE INDEX
test=*# set enable_seqscan to false;
SET
test=*# explain select * from blafasel where c1=1 and c2=2 and c3= 3 and c4=4;
  QUERY PLAN   
-----------------------------------------------------------------------------------
 Index Only Scan using idx_blafasel on blafasel  (cost=0.15..8.18 rows=1 width=16)
  Index Cond: ((c1 = 1) AND (c2 = 2) AND (c3 = 3) AND (c4 = 4))
(2 Zeilen)

test=*# explain select * from blafasel where c4=4 and c3=3 and c2=2 and c1=1;
  QUERY PLAN   
-----------------------------------------------------------------------------------
 Index Only Scan using idx_blafasel on blafasel  (cost=0.15..8.18 rows=1 width=16)
  Index Cond: ((c1 = 1) AND (c2 = 2) AND (c3 = 3) AND (c4 = 4))
(2 Zeilen)

test=*#

Das ist also Banane, wie im Where die Reihenfolge ist.
 
Vielen Dank für deine Mühe :)

ok also für die ganz dummen:

Anzahl der unterschiedlichen Elemente für jede Spalte ermitteln, welche im Index enthalten sein soll und dann die Spalte mit den geringsten unterschiedlichen Elementen am Anfang des Index usw.

Richtig ?

Oder wäre es wichtiger die Kombination zu finden, welche die geringste Gesamt-Kardinalität (Kardinalität aller Spalten im Index) ergibt?
 
ja, die Spalten, die am selektivsten sind, zuerst im Index. Bzw, wenn Du z.B. hast: "WHERE id=42 and ts > now() order by x", dann sollte der Index über (id, ts, x) gehen.
 
Werbung:
Zurück
Oben