Bonjour à tous,
J'ai un souci d'optimisation de requête avec une vue. La vue elle-même n'a pas d'importance. Sachez juste qu'elle est assez lourde, contient des distinct, group by, listagg (oracle), connect by prior (oracle), min, sum, ... Bref, que du beau monde. Le cas énoncé ci-dessous fonctionne pour toute vue. Appelons la v_client.
Le problème est le suivant.
Si une requête est exprimée de la sorte (exemple construit de toutes pièces):
Imaginons que cette requête me fournit les résultats suivants:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 SELECT v_client.id_personne, compte.id_compte FROM compte, v_client WHERE v_client.id_personne = compte.id_personne AND compte.cod_type = 'COMPLET'
Imaginons maintenant que l'on reformule la requête de la façon suivante (on lui fournit directement les ID):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 V_CLIENT.ID_PERSONNE | COMPTE.ID_COMPTE ------------------------------------------------------------ 4545 | 46 4648 | 87 5345 | 89
Si le nombre de lignes dans la vue est grand, les performances de la première requête sont exécrables. Le problème ne se pose pas si il s'agit d'une table à la place d'une vue. Un work-around est de reformuler la première requête de la façon suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 SELECT v_client.id_personne, compte.id_compte FROM compte, v_client WHERE v_client.id_personne = compte.id_personne AND compte.cod_type = 'COMPLET' AND v_client.id_personne IN ( 4545, 4648, 5345 )
Mais si l'on désire obtenir tous les champs de la vue, cela va dupliquer le nombre de clause SELECT et va donc aussi faire augmenter le temps de résolution (mais dans une moindre mesure).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 SELECT compte.id_compte, (SELECT v_client.id_personne FROM v_client WHERE v_client.id_personne = compte.id_personne) FROM compte WHERE compte.cod_type = 'COMPLET'
Si l'on regarde l'explain plan d'Oracle, on remarque qu'il est normal que le 1er cas soit plus lourd que le 2ème car dans le 1er cas, le sgbd va d'abord faire un retrieve complet sur la vue AVANT de faire la jointure dans la clause where. Dans le 2ème cas, comme on lui fournit les ID, le retrieve complet sur la vue n'est pas fait. Dans le troisième cas (le word-around), je force le schéma de résolution en lui fournissant la jointure dans la clause select, et le sgbd suit alors le bon schéma de résolution.
Alors moi je dis: WTF Comment qu'on fait pour exprimer la première requête et lui demandant de suivre le bon schéma de résolution? J'ai regardé du coté des HINTs Oracle, mais rien ne semble vraiment convenir...
Partager