Oracle
 sql >> Base de données >  >> RDS >> Oracle

Différence entre clause WITH et sous-requête ?

Le WITH La clause est destinée à la factorisation des sous-requêtes, également appelées expressions de table communes ou CTE :

La clause WITH query_name vous permet d'attribuer un nom à un bloc de sous-requête. Vous pouvez ensuite référencer le bloc de sous-requête à plusieurs endroits dans la requête en spécifiant query_name. Oracle Database optimise la requête en traitant le nom de la requête comme une vue en ligne ou comme une table temporaire.

Dans votre deuxième exemple, ce que vous avez appelé temp_table est une vue en ligne, pas une table temporaire.

Dans de nombreux cas, le choix de celui à utiliser dépend de votre style préféré, et les CTE peuvent rendre le code plus lisible, en particulier avec plusieurs niveaux de sous-requêtes (les opinions varient bien sûr). Si vous ne vous référez qu'une seule fois à la vue CTE/en ligne, vous ne verrez probablement aucune différence de performances, et l'optimiseur peut se retrouver avec le même plan.

Ils sont particulièrement utiles lorsque vous devez utiliser la même sous-requête à plusieurs endroits, comme dans une union. Vous pouvez extraire une vue en ligne dans un CTE afin que le code ne soit pas répété, et cela permet à l'optimiseur de le matérialiser s'il pense que cela serait bénéfique.

Par exemple, cet exemple artificiel :

select curr from (
  select curr from tableone t1
  left join tabletwo t2 on (t1.empid = t2.empid)
) temp_table
where curr >= 0
union all
select -1 * curr from (
  select curr from tableone t1
  left join tabletwo t2 on (t1.empid = t2.empid)
) temp_table
where curr < 0

pourrait être refactorisé en :

with temp_table as (
  select curr from tableone t1
  left join tabletwo t2 on (t1.empid = t2.empid)
)
select curr from temp_table
where curr >= 0
union all
select -1 * curr from temp_table
where curr < 0

La sous-requête n'a plus besoin d'être répétée. Plus le code répété est compliqué, plus il est avantageux du point de vue de la maintenance d'utiliser un CTE. Et plus la sous-requête est chère, plus vous pourriez améliorer les performances voir en utilisant un CTE, bien que l'optimiseur soit généralement assez bon pour comprendre ce que vous faites de toute façon.