Bonjour à tous.
Je débute l'étude du plan d'exécution, et j'avoue qu'il y a une chose qui m'échappe dans ce qui suit.
Le problème : j'ai une grosse table d'environ 80 millions de ligne. Les requêtes qui l'attaquent filtrent une de ses colonnes d'après un ensemble de valeur dans un IN. Cette colonne peut prendre environ 400 valeurs différentes.
Voici une requête que l'on pourraît passer sur cette table, et son plan d'exécution :La requête est longue vu que pour chaque valeur dans le IN, on scanne l'index puis la table (enfin, d'après ce que je comprends de ce plan...).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 SELECT Id, colonne_filtree, autre_colonne FROM grande_table WHERE colonne_filtree IN ('100', '102', '200', '202') AND autre_colonne = '200612' Plan d'exécution ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=11525 Card=12779 Bytes=306696) 1 0 INLIST ITERATOR 2 1 TABLE ACCESS (BY INDEX ROWID) OF 'GRANGE_TABLE' (Cost=11525Card=12779 Bytes=306696) 3 2 INDEX (RANGE SCAN) OF 'IDX_GRANGE_TABLE' (NON-UNIQUE) (Cost=52 Card=12779)
J'ai donc voulu utiliser une autre table qui contient les 400 codes présents dans colonne_filtree pour que l'itération se fasse sur cette petite table avant d'opérer une jointure sur ma grande table.Donc si je comprends bien, le INLIST ITERATOR va bien chercher dans ma petite_table (plutôt dans son index), mais aussi dans celui de ma grande_table ! Certe, cette fois-ci, la table elle-même n'est scannée qu'en fin de traitement, mais son index reste dans l'itérateur...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 SELECT Id, colonne_filtree, autre_colonne FROM petite_table, grande_table WHERE code = colonne_filtree AND code IN ('100', '102', '200', '202') AND autre_colonne = '200612' Plan d'exécution ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=326 Card=133 Bytes=3724) 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'GRANDE_TABLE' (Cost=81 Card=33 Bytes=792) 2 1 NESTED LOOPS (Cost=326 Card=133 Bytes=3724) 3 2 INLIST ITERATOR 4 3 INDEX (RANGE SCAN) OF 'IDX_PETITE_TABLE' (UNIQUE) (Cost=2 Card=4 Bytes=16) 5 2 INLIST ITERATOR 6 5 INDEX (RANGE SCAN) OF 'IDX_GRANDE_TABLE' (NON-UNIQUE) (Cost=51 Card=33)
C'est normal ??
Est-ce que je comprends tout de travers ??
Partager