News zu Oracle

SQL Tuning Tipp: „SELECT 0“ in einer [NOT] EXISTS-Subquery

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 erfor­derlich (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 verwen­deten Indexes ist. Auch aktuelle Optimizerversionen bügeln diesen faux-pax bereits im Hintergrund aus. Andernfalls muss zum Ermitteln des Spaltenwertes unnöti­ger­weise 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 unper­for­manter als EXISTS / IN, da das Aggregat in jedem Fall errechnet wird. Unabhängig davon, gegen welchen Wert es letzt­endlich 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 |
-------------------------------------------------------------------------------------
Hier findest du weitere Posts zu den Themen SQL Tuning bzw. Performance Tuning aus unserem News Bereich. 
icon-arrow_right_medium-violet-blue.svg

Share this article

Facebook 
Twitter 
LinkedIn 
XING 
WhatsApp 
Email