Capturer un plan pour le forcer /*+ Mauvaise idee */

Ce que je vais décrire ci-dessous est sûrement une très mauvaise idée, si c’est mal utilisé. Toutefois, imaginer le cas suivant :

  • Vous avez une requête qui s’exécute sur un serveur Oracle 9i/8i avec un certain plan.
  • Vous le migrer sur un nouveau serveur en 10g et son plan change.
  • Comment comparer le gain (ou la perte) dûe au nouveau plan ?

Une idée possible, peut-être d’utiliser le paramètre COMPATIBLE=9.2.0 sur votre base 10g. C’est toutefois pas évident d’être sûr que le plan sera identique car les statistiques sont clés et il est probable que vous changiez de méthode de prise de statistiques (J’ai un super fit en 10g avec l’option method_opt=>’FOR ALL COLUMNS SIZE AUTO’ de DBMS_STATS)

Une autre idée consiste à forcer le plan de votre 9i au moyen de HINTS. Le problème si votre plan fait 3369 étapes et 5 niveaux de vues, c’est que c’est pas évident à reconstruire, pour vous aider :

  • Je ne suis pas un admirateurs des outlines (D’ailleurs, ça sera remplacé par un truc beaucoup plus sioux en 11.1 !) mais en l’occurence, ça peut vous aider pour ce problème. Regardez les vues USER_OUTLINE_HINTS et la commande CREATE OUTLINE. (pour en savoir plus, regardez cet article de Jonathan Lewis (Encore lui !).
  • EN 10g (et pas avant, dommage), l’event 10053 (C’est là où je voulais en venir !) affiche en fin de plan un HINT permettant de figer le plan… Les migrations vers la 11, vont être enfantines. Ci-dessous un exemple.

SQL> alter session set events '10053 trace name context forever';

SQL> select /* event 10053 */ e.empno, d.loc
from dept d, emp e
where empno>1000
and d.deptno=e.empno;

SQL> alter session set events '10053 trace name context off';

Attention, il faut que la requête soit parsée pour que le fichier soit généré (d'où l'utilité du commentaire. Ensuite, il faut se déconnecter et de regarder le fichier généré dans le répertoire correspondant au paramètre user_dump_dest (ou $ORACLE_BASE/admin/{DBNAME}/udump en OFA). En dessous de la trace effective du calcul du plan, vous avez les informations correspondant à l’OUTLINE qui s’affiche :

$ ls -ltr
-rw-r—– 1 oracle oinstall 38243 Mar 22 13:57 orcl_ora_4209.trc

cat
orcl_ora_4209.trc

db_version : 10.2.0.3
parse_schema : SCOTT
plan_hash : 459569910
Outline Data:
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.3')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "E"@"SEL$1" ("EMP"."EMPNO"))
INDEX_RS_ASC(@"SEL$1" "D"@"SEL$1" ("DEPT"."DEPTNO"))
LEADING(@"SEL$1" "E"@"SEL$1" "D"@"SEL$1")
USE_NL(@"SEL$1" "D"@"SEL$1")
END_OUTLINE_DATA
*/

GarK!