Une petite polémique avait débuté avec le hint APPEND et Oracle 11.1. En effet Oracle avait alors modifié son fonctionnement pour supporter le hint avec la clause VALUES d’un ordre INSERT. Depuis, ils sont, sans doute, revenus en arrière. Personnellement je trouvais l’idée très séduisante et j’ai d’ailleurs écrit plusieurs articles à ce sujet puisque ça ouvrait la porte à l’écriture de programmes Pro*C, OCI ou PL/SQL qui pouvaient intégrer des données de manière massive, sans logs et sans insert as select
ni tables externes.
D’autres, sans doute plus pragmatiques, mettaient en avant que si un programme fonctionnait en 10g et qu’un développeur avait par mégarde ajouté ce hint à un insert ... values
, la table serait lockée en mode exclusif le temps de la transaction associée et le High Water Mark déplacé, même pour une ligne. Les conséquences d’une mauvaise utilisation pouvaient donc être catastrophiques. J’avoue que, dans une première approche au moins, punir les gens qui utilisent des hints sans savoir pourquoi ne faisait qu’ajouter à mon plaisir… Enfin, on peut imaginer des situations assez compliquées pour migrer en 11g. Malheureux ceux qui n’auraient pas testé !
Oracle 11.2 coupe donc la poire en 2 en intégrant la fonctionnalité du hint APPEND
avec une clause VALUES
mais en changeant le nom du hint pour tous les mauvais développeurs ne soient pas punis malgré tout. Dans cet article, je reprends l’exemple que j’avais écrit à l’époque et qui est toujours disponible sur mon ancien blog mais en changeant les hints utilisés.
Note:
Le numéro et le nom de la statisque ont également changé en 11.2; j’ai donc modifié l’exemple en conséquence.
Tests avec les Hints APPEND_VALUES
et APPEND
Le script ci-dessous crée un schéma et une table d’exemple; il calcule le nombre de blocs écrits en mode directs avec les hints APPEND
et APPEND_VALUES
:
create user demo identified by demo default tablespace users temporary tablespace temp; grant connect, resource to demo; grant select on sys.v_$mystat to demo; grant select on sys.v_$statname to demo; connect demo/demo define myhint = "append_values" prompt &&myhint create table insertappend (id number, text varchar2(200)); set serveroutput on declare id dbms_utility.number_array; text dbms_utility.lname_array; dpw number; begin select m.value into dpw from v$mystat m, v$statname s where s.statistic#=m.statistic# and s.name='physical writes direct'; for i in 1..10000 loop id(i) := i; text(i) := to_char(i); end loop; forall i in 1..10000 insert /*+ &&myhint */ into insertappend(id,text) values (id(i),text(i)); select m.value-dpw into dpw from v$mystat m, v$statname s where s.statistic#=m.statistic# and s.name='physical writes direct'; dbms_output.put_line( '"Physical Write Direct" avec le Hint &&myhint : ' ||to_char(dpw)); end; /
Le résultat est le suivant sur mon laptop :
"Physical Write Direct" avec le Hint append_values : 20
Vous pouvez effectuer la même opération avec le Hint APPEND; Il n’y a pas d’écritures en mode direct en 11.2:
define myhint = "append" prompt &&myhint / "Physical Write Direct" avec le Hint append : 0
Convaincu? Vous pouvez supprimer la table et l’utilisateur :
drop table demo.insertappend purge; drop user demo cascade;
Et restez dans les environs, il y a encore beaucoup de nouvelles fonctionnalités que nous allons explorer dans les jours qui viennent….