Problème de schéma de résolution avec une vue
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):
Code:
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 que cette requête me fournit les résultats suivants:
Code:
1 2 3 4 5 6
|
V_CLIENT.ID_PERSONNE | COMPTE.ID_COMPTE
------------------------------------------------------------
4545 | 46
4648 | 87
5345 | 89 |
Imaginons maintenant que l'on reformule la requête de la façon suivante (on lui fournit directement les ID):
Code:
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 ) |
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:
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' |
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).
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 :cfou:. 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...