News & Events
SQL Tuning Tipp: Entfernen überflüssiger Indizes

Unter Umständen kann auf Indizes verzichtet werden, deren Spalten eine Ober- oder Untermenge bereits existierender Indizes sind.

Icon Unternehmen

Indizes beschleunigen auf der einen Seite zwar selektive Datenzugriffe. Auf der anderen Seite verursachen sie aber auch Overhead bei DML-Operationen, belegen Platz in der Datenbank und im Backup sowie verursachen zum Teil signifikante Ladezeiten beim Import ieren von Dumps. Wenn gleich die Einsparung von Indizes in der Regel keinen Performance-Boost verursacht, sollte mit Indizierung so sparsam wie möglich umgegangen werden.

Beispiel: Die Tabelle EMPLOYEES enthält zwei Indizes

EMP_NAME_IX auf den Spalten LAST_NAME und FIRST_NAME und
EMP_LAST_NAME_IDX auf der Spalte LAST_NAME

Eine Query auf  LAST_NAME und FIRST_NAME würde natürlich ideal bedient vom Index EMP_NAME_IX. Die komplette WHERE-Klausel kann über den Index abgehandelt werden:

SELECT * 
FROM employees
WHERE last_name = 'Gates' AND first_name = 'Timothy';
-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |     1 |    69 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES   |     1 |    69 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_NAME_IX |     1 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("LAST_NAME"='Gates' AND "FIRST_NAME"='Timothy')

Verzichtet man jedoch auf den Index EMP_NAME_IX, der eine Obermenge von EMP_LAST_NAME_IDX ist, kann immer noch von der Indizierung profitiert werden – auf Kosten eines etwas höheren CPU-Aufwandes für das nun zusätzlich erforderliche Filtern von

FIRST_NAME:
SELECT * 
FROM employees
WHERE last_name = 'Gates'
AND first_name = 'Timothy';
-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   |     1 |    69 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |     1 |    69 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_LAST_NAME_IDX |     1 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("FIRST_NAME"='Timothy')
   2 - access("LAST_NAME"='Gates')

 

 


Newsletter-Archiv