MIN- oder MAX- Bildung per Index - Lambertz

Werbung
Lambertz
onsulting
________________________________________________________________________________________________
Rainer Lambertz, Kreuzstraße 54, 41564 Kaarst,
E-Mail: [email protected]
Internet: http://www.lambertz-consulting.de
MIN oder MAX Bildung per B*Tree Index Hint
Zugegeben, der Trick Min- oder Maximalwerte per Index Hint zu ermitteln ist nicht neu.
Gewöhnlich sind mit diesem Trick Laufzeitverbesserungen zu erzielen, jedoch nicht
unbedingt. Aber wann lohnt sich der Einsatz und unter welchen Umständen ist eine
Verschlechterung der Laufzeit zu erwarten?
Folgende Tabelle liegt vor..
SQL > DESC adressen;
Name
Null?
------------------------------- -------ANREDE
VORNAME
NAME
STRASSE
PLZ
ORT
TELEFON
VORWAHL
RUFNUMMER
Type
---VARCHAR2(10)
VARCHAR2(25)
VARCHAR2(90)
VARCHAR2(60)
NUMBER(5)
VARCHAR2(60)
VARCHAR2(15)
NUMBER(10)
VARCHAR2(30)
..mit folgendem Index:
SQL > SELECT TABLE_NAME, COLUMN_NAME, COLUMN_POSITION
FROM all_ind_columns
WHERE index_name = 'ADRESSEN_IDX01';
TABLE_NAME
-----------------------------ADRESSEN
ADRESSEN
COLUMN_NAME
COLUMN_POSITION
-------------- --------------PLZ
1
VORWAHL
2
Die Abfrage nach der größten PLZ für die Vorwahl „07774“ lautet:
SQL > SELECT MAX( plz )
FROM adressen
WHERE vorwahl = 7774;
MAX(PLZ)
---------78267
1 row selected.
real: 3426
_____________________________________________________________________________________
MIN- oder MAX- Bildung per Index
Seite 1
Lambertz
onsulting
________________________________________________________________________________________________
Rainer Lambertz, Kreuzstraße 54, 41564 Kaarst,
E-Mail: [email protected]
Internet: http://www.lambertz-consulting.de
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Cost=7 Optimizer=CHOOSE
1
0
SORT (AGGREGATE)
2
1
INDEX (FAST FULL SCAN) OF 'ADRESSEN_IDX01'
Statistics
---------------------------------------------------------0 recursive calls
10 db block gets
4405 consistent gets
Um die größte PLZ zu ermitteln, nutzt Oracle den Index ADRESSEN_IDX01. Auf den
ersten Blick nicht schlecht.
Die Anzahl CONSISTENT GETS verraten jedoch, daß 4405 Datenblöcke herangezogen
wurden, die maximale PLZ zu ermitteln. Ursache ist der FAST FULL SCAN des Indizes.
Unter dem Aspekt, daß der Index aufsteigend sortiert vorliegt, befindet sich die größte
PLZ im letzten Eintrag, welcher der WHERE Bedingung entspricht. Es ist also nicht
erforderlich den gesamten Index zu lesen. Dies wird erreicht durch folgendes Statement:
SQL > SELECT /*+ INDEX_DESC( adressen adressen_idx01 ) */
2
plz
3
FROM adressen
4
WHERE vorwahl = 7774
5
AND ROWNUM =1;
PLZ
---------78267
1 row selected.
real: 200
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Cost=26 Optimizer=CHOOSE
1
0
COUNT (STOPKEY)
2
1
INDEX (FULL SCAN DESCENDING) OF 'ADRESSEN_IDX01'
Statistics
---------------------------------------------------------8 recursive calls
0 db block gets
251 consistent gets
_____________________________________________________________________________________
MIN- oder MAX- Bildung per Index
Seite 2
Lambertz
onsulting
________________________________________________________________________________________________
Rainer Lambertz, Kreuzstraße 54, 41564 Kaarst,
E-Mail: [email protected]
Internet: http://www.lambertz-consulting.de
Mit dem Hint INDEX_DESC wird der Index vom Ende her gelesen. ROWNUM=1
bestimmt, daß der Scanvorgang beendet wird, sobald der erste Eintrag im Index der
WHERE Bedingung (VORWAHL=7774) entspricht.
An dieser Stelle erfolgt ein FULL SCAN statt eines FAST FULL SCAN und ist ein
schlechterer Indexzugriff. Jedoch fällt die Anzahl CONSISTENT GETS mit 251
wesentlich geringer aus und die Laufzeit liegt mit 200 ms auch besser.
Nun, welchen Laufzeitgewinn bringt der Einsatz eines entsprechenden Hint für das
Ermitteln der kleinsten PLZ einer VORWAHL. Zu Beginn wieder der Einsatz der
entsprechenden Funktion.
SQL >
2
3
SELECT MIN( plz )
FROM adressen
WHERE vorwahl = 7774;
MIN(PLZ)
---------78267
1 row selected.
real: 3352
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Cost=1053 Optimizer=CHOOSE
1
0
SORT (AGGREGATE)
2
1
INDEX (FAST FULL SCAN) OF 'ADRESSEN_IDX01'
Statistics
---------------------------------------------------------0 recursive calls
4 db block gets
4405 consistent gets
Zeitlich ist kaum ein Unterschied zum Einsatz der MAX Funktion zu erkennen. Die
Anzahl CONSISTENT GETS ist für die MIN und MAX Bildung in beiden Fällen identisch.
Ursache ist, daß der Index in beiden Fällen komplett gescannt wurde.
Das Select Statement mit entsprechendem Hint lautet nun:
SQL >
2
3
4
SELECT /*+ INDEX_ASC( adressen adressen_idx01 ) */
plz
FROM adressen
WHERE vorwahl = 7774
_____________________________________________________________________________________
MIN- oder MAX- Bildung per Index
Seite 3
Lambertz
onsulting
________________________________________________________________________________________________
Rainer Lambertz, Kreuzstraße 54, 41564 Kaarst,
E-Mail: [email protected]
Internet: http://www.lambertz-consulting.de
5
AND ROWNUM =1;
PLZ
---------78267
1 row selected.
real: 4989
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Cost=4397 Optimizer=CHOOSE
1
0
COUNT (STOPKEY)
2
1
INDEX (FULL SCAN) OF 'ADRESSEN_IDX01'
Statistics
---------------------------------------------------------0 recursive calls
0 db block gets
4170 consistent gets
Die Laufzeit hat sich gegenüber der MIN Funktion verschlechtert, obwohl die Anzahl
CONSISTENT GETS geringer ausfallen –wenn auch nicht wesentlich.
Für das Emitteln des Maximalwertes wurden 251 Blöcke benötigt und für den
Minimalwert waren 4170 Blöcke erforderlich.
SQL > SELECT /*+ INDEX_FFS( adressen adressen_idx01 ) */
2
plz
3
FROM adressen
4
WHERE vorwahl = 7774
5
AND ROWNUM =1;
PLZ
---------78267
1 row selected.
real: 3042
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Cost=1053 Optimizer=CHOOSE
1
0
COUNT (STOPKEY)
2
1
INDEX (FAST FULL SCAN) OF 'ADRESSEN_IDX01'
Statistics
_____________________________________________________________________________________
MIN- oder MAX- Bildung per Index
Seite 4
Lambertz
onsulting
________________________________________________________________________________________________
Rainer Lambertz, Kreuzstraße 54, 41564 Kaarst,
E-Mail: [email protected]
Internet: http://www.lambertz-consulting.de
---------------------------------------------------------0 recursive calls
4 db block gets
4159 consistent gets
Da standardmäßig der Index ASC gelesen wird, kann der Minimalwert über den Hint
INDEX_FFS erfolgen, weil FAST FULL SCAN einfach schneller das Ergebnis
bestimmen kann.
Die Summe der CONSISTENT GETS für die Min und Max Bildung per Index Hint, liegt
mit 4421 (bzw. 4410 für den FAST FULL SCAN) recht dicht an den 4405 Datenblöcken,
die benötigt wurden den gesamten Index zu scannen. Darin liegt die Ursache für die
unterschiedlichen Laufzeiten bei der Ermittlung der MIN und MAX Werte per Index. Der
Maximalwert lag weit vorne im Index und somit mußte gesamte Rest des Index (von
hinten nach vorne) gelesen werden um die minimale PLZ zu bestimmen. Beiläufig ist
erkennbar, daß ein B*tree Index tatsächlich über eine rückwärtige Verkettung aller
Indexeinträge verfügt.
_____________________________________________________________________________________
MIN- oder MAX- Bildung per Index
Seite 5
Herunterladen