/*+ dynamic_sampling(n) */

J’ai déjà parlé du « dynamic sampling ». Bien comprendre son principe et ses effets est très important puisque si des tables n’ont pas de statistisques, le moteur 10g est généralement amené à utiliser cette méthode pour évaluer les statistiques tout en créant le plan d’exécution (cf paramètre optimizer_dynamic_sampling qui est à 2 par défaut en 10.2).

L’exemple de l’époque était assez compliquer. Dans ce qui suit, voici un exemple bien plus simple. Il a été réalisé avec Oracle 10.2.0.3

Setup du cas
create table gark (a number, b number);

insert into gg
(select rownum, rownum
from dba_objects, dba_objects, dba_objects
where rownum<=150000);

commit;

create index gark_idx on gark(a);

exec dbms_stats.gather_table_stats(USER, ‘GARK’, –
estimate_percent=>null, –
cascade=>true, –
no_invalidate=>false, –
method_opt=>’for all columns size 254′)

La requête
Examinez ensuite les plans et statistiques de la requête suivante (1) sans dynamic sampling

select /*+ no_hint */ count(a.ROWID)
from gark a, gark b
where a.a=a.b
and b.a=a.a and b.a=b.b;

Puis avec dynamic sampling
select /*+ dynamic_sampling(10) */ count(a.ROWID)
from gark a, gark b
where a.a=a.b
and b.a=a.a and b.a=b.b;

Et voilà, le résultat est très impressionnant, non ? Réfléchissez avec quelle méthode intelligente (C’est à dire pas USE_HASH… Et si la distribution corrélée de a et de b a complètement changée dans 3 heures !). Un commentaire peut-être ?

GarK!