web-dev-qa-db-fra.com

L'optimiseur Oracle utilisera-t-il plusieurs astuces dans le même SELECT?

J'essaie d'optimiser les performances des requêtes et j'ai dû recourir à des conseils d'optimisation. Mais je n'ai jamais appris si l'optimiseur utilisera plus d'un indice à la fois.

par exemple.

SELECT /*+ INDEX(i dcf_vol_prospect_ids_idx)*/
       /*+ LEADING(i vol) */ 
       /*+ ALL_ROWS */ 
       i.id_number,
       ...
  FROM i_table i
  JOIN vol_table vol on vol.id_number = i.id_number
  JOIN to_a_bunch_of_other_tables...
 WHERE i.solicitor_id = '123'
   AND vol.solicitable_ind = 1;

Le plan d'explication montre le même coût, mais je sais que ce n'est qu'une estimation.

Veuillez supposer que toutes les statistiques de table et d'index ont été calculées. Pour info, l'index dcf_vol_prospect_ids_idx est sur la colonne i.solicitor_id.

Merci,

Ragoût

19
Stew S

Essayez de spécifier tous les conseils dans un seul bloc de commentaires, comme indiqué dans cet exemple de la merveilleuse documentation Oracle ( http://download.Oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref. htm ).

16.2.1 Spécification d'un ensemble complet d'indices

Lors de l'utilisation d'indices, dans certains cas, vous devrez peut-être spécifier un ensemble complet d'indices afin d'assurer le plan d'exécution optimal. Par exemple, si vous avez une requête très complexe, qui se compose de plusieurs jointures de table, et si vous spécifiez uniquement l'indicateur INDEX pour une table donnée, l'optimiseur doit déterminer les chemins d'accès restants à utiliser, ainsi que les chemins d'accès correspondants. joindre des méthodes. Par conséquent, même si vous avez donné l'indicateur INDEX, l'optimiseur peut ne pas nécessairement utiliser cet indice, car l'optimiseur peut avoir déterminé que l'index demandé ne peut pas être utilisé en raison des méthodes de jointure et des chemins d'accès sélectionnés par l'optimiseur.

Dans l'exemple 16-1, l'indicateur LEADING spécifie l'ordre de jointure exact à utiliser; les méthodes de jointure à utiliser sur les différentes tables sont également spécifiées.

Exemple 16-1 Spécification d'un ensemble complet d'indices

SELECT /*+ LEADING(e2 e1) USE_NL(e1) INDEX(e1 emp_emp_id_pk)
           USE_MERGE(j) FULL(j) */
    e1.first_name, e1.last_name, j.job_id, sum(e2.salary) total_sal  
FROM employees e1, employees e2, job_history j
WHERE e1.employee_id = e2.manager_id
  AND e1.employee_id = j.employee_id
  AND e1.hire_date = j.start_date
GROUP BY e1.first_name, e1.last_name, j.job_id   ORDER BY total_sal;
22
Dave Costa

En fait, la recommandation de Jonathan Lewis, auteur de Oracle Fund-Based Oracle Fundamentals, est que si le CBO ne parvient pas à trouver le bon plan, vous devez reprendre le travail du CBO et "superposer" les indices - une moyenne de deux conseils par table dans la requête.

La raison en est qu'un indice pourrait conduire à un autre mauvais plan et peut-être même pire que celui du CBO. Si le CBO se trompe, vous devez lui donner tout le plan, pas seulement un coup de pouce dans la bonne direction.

2
Mark Brady

Oracle 19c a été introduit fonction de rapport d'utilisation des conseils :

EXPLAIN PLAN FOR
SELECT /*+ INDEX(i dcf_vol_prospect_ids_idx)*/
       /*+ LEADING(i vol) */ 
       /*+ ALL_ROWS */ 
       i.id_number,
       ...
  FROM i_table i
  JOIN vol_table vol on vol.id_number = i.id_number
  JOIN to_a_bunch_of_other_tables...
 WHERE i.solicitor_id = '123'
   AND vol.solicitable_ind = 1;

SELECT * FROM table(DBMS_XPLAN.DISPLAY(FORMAT=>'BASIC +HINT_REPORT'));
                                                     --============

Il montre une autre section Hint Report:

Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: ...
---------------------------------------------------
...
2
Lukasz Szozda