News zu Oracle

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

Der aktuelle SQL Tuning Tipp be­schäf­tigt sich mit der Op­ti­mie­rung einer Subquery. Wenn nur die Existenz der Er­geb­nis­zei­le in einer Subquery von Interesse ist, ist es nicht er­for­der­lich (teils sogar schädlich), konkrete Ta­bel­len­spal­ten oder gar Aggregate zu selektieren.

Das Se­lek­tie­ren einer konkreten Spalte ist schadlos, wenn diese Spalte Be­stand­teil eines in der Subquery sowieso ver­wen­de­ten Indexes ist. Auch aktuelle Op­ti­mi­zer­ver­sio­nen bügeln diesen faux-pax bereits im Hin­ter­grund aus. An­dern­falls muss zum Ermitteln des Spal­ten­wer­tes un­nö­ti­ger­wei­se zu­sätz­lich zum Index- noch ein Ta­bel­len­zu­griff erfolgen.

Aggregate ( z.B. count() ) in einer Subquery, die für den Test auf Ent­hal­ten­sein genutzt wird, ist un­per­for­man­ter als EXISTS / IN, da das Aggregat in jedem Fall errechnet wird. Un­ab­hän­gig davon, gegen welchen Wert es letzt­end­lich ver­gli­chen 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 |
-----------------------------------------------------------------------------------------

Schlech­tes 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. Per­for­mance Tuning aus unserem News Bereich. 
icon-arrow_right_medium-violet-blue.svg

Share this article

Facebook 
Twitter 
LinkedIn 
XING 
WhatsApp 
Email