Der aktuelle SQL Tuning Tipp beschäftigt sich mit der Optimierung einer Subquery. Wenn nur die Existenz der Ergebniszeile in einer Subquery von Interesse ist, ist es nicht erforderlich (teils sogar schädlich), konkrete Tabellenspalten oder gar Aggregate zu selektieren.
Das Selektieren einer konkreten Spalte ist schadlos, wenn diese Spalte Bestandteil eines in der Subquery sowieso verwendeten Indexes ist. Auch aktuelle Optimizerversionen bügeln diesen faux-pax bereits im Hintergrund aus. Andernfalls muss zum Ermitteln des Spaltenwertes unnötigerweise zusätzlich zum Index- noch ein Tabellenzugriff erfolgen.
Aggregate ( z.B. count() ) in einer Subquery, die für den Test auf Enthaltensein genutzt wird, ist unperformanter als EXISTS / IN, da das Aggregat in jedem Fall errechnet wird. Unabhängig davon, gegen welchen Wert es letztendlich verglichen wird.
Gutes Beispiel
SELECT *
FROM employees m
WHERE EXISTS (
SELECT 0 --oder e.manager_id
FROM employees e
WHERE e.manager_id = m.employee_id);
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 31250 | 3448K| 4798 (1)| 00:00:58 |
|* 1 | HASH JOIN | | 31250 | 3448K| 4798 (1)| 00:00:58 |
| 2 | SORT UNIQUE | | 1000K| 12M| 9 (0)| 00:00:01 |
| 3 | INDEX FAST FULL SCAN| EMP_MANAGER_IX | 1000K| 12M| 9 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | EMPLOYEES | 1000K| 95M| 38 (24)| 00:00:01 |
-----------------------------------------------------------------------------------------
Schlechtes Beispiel
SELECT *
FROM employees m
WHERE (
SELECT count(*)
FROM employees e
WHERE m.manager_id = e.employee_id) > 0;
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000K| 95M| 855K (1)| 02:51:02 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL | EMPLOYEES | 1000K| 95M| 40 (28)| 00:00:01 |
| 3 | SORT AGGREGATE | | 1 | 13 | | |
|* 4 | INDEX UNIQUE SCAN| EMP_EMP_ID_PK | 1 | 13 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Share this article
Sie müssen den Inhalt von reCAPTCHA laden, um das Formular abzuschicken. Bitte beachten Sie, dass dabei Daten mit Drittanbietern ausgetauscht werden.
Mehr InformationenSie sehen gerade einen Platzhalterinhalt von Facebook. Um auf den eigentlichen Inhalt zuzugreifen, klicken Sie auf die Schaltfläche unten. Bitte beachten Sie, dass dabei Daten an Drittanbieter weitergegeben werden.
Mehr Informationen