Bonjour,
Est ce qu'une requête sur une table détails, doit être identique à celle de la création de la vue matérialisée utilisant cette table pour qu'elle soit réécrite en utilisant cette vue matérialisée?
Bonjour,
Est ce qu'une requête sur une table détails, doit être identique à celle de la création de la vue matérialisée utilisant cette table pour qu'elle soit réécrite en utilisant cette vue matérialisée?
Non, en fait l'Optimizer va chercher à utiliser le QUERY REWRITE si :Exemple :
- Si le texte de la requête est syntaxiquement le même.
- Si le texte de la requête n'est pas le même mais que les éléments du select, du from et du where reviennent mathématiquement à la même chose.
- Si les tables impactées sont toutes locales.
Est identique pour lui à :
Code : Sélectionner tout - Visualiser dans une fenêtre à part select a,b,c from t where a=1 and b=3;
Pour plus d'informations, lit le bouquin : Oracle® Database Data Warehousing Guide 10g Release 2 (10.2) : Part V §17
Code : Sélectionner tout - Visualiser dans une fenêtre à part select c,a,b from t where b=3 and a=1;
merci pour ta réponse... mais je crois que je me suis mal exprimé.
pour être plus précis :
Voici la requête de création de la vue matérialisée :
et voici la requête qui devrait être réécrite par oracle:
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
16 SELECT ID_DATE, CALL_DIRC, CALL_TYP, CALL_TYP2, COUNT(*) as "NOMB_APPL", SUM(VOLM) as "VOLM", SUM(CHFF_AFFR_HT) as "CHFF_AFFR_HT", SUM(COUT_HT) as "COUT_HT" FROM TICKETS_INTERCO TI WHERE NOT EXISTS ( SELECT 1 FROM NUMERO_EXCLU NE WHERE TI.CALLING_NUMB_BILL = NE.NUMR_TELP OR TI.CALLED_NUMB_BILL = NE.NUMR_TELP ) GROUP BY ID_DATE, CALL_DIRC, CALL_TYP, CALL_TYP2
le plan d'exécution indique un passage par l'index de date pour parcourir la table tickets_interco.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 Select ID_DATE, count(*) as "NB_APPL", SUM(CASE WHEN (CALL_DIRC='OUT' AND CALL_TYP2 in ('1','15')) THEN 0 ELSE NVL(VOLM,0) END) as "VOLM" From [Datamart Trafic].TICKETS_INTERCO TI Where ID_DATE between '01/01/2008' AND '07/01/2008'-->= sysdate() - 7 AND NOT EXISTS ( SELECT 1 FROM [Datamart Trafic].NUMERO_EXCLU NE WHERE TI.CALLING_NUMB_BILL = NE.NUMR_TELP OR TI.CALLED_NUMB_BILL = NE.NUMR_TELP ) Group By ID_DATE
pourriez vous m'indiquer sur quel niveau ça bloque?
D'un point de vue analytique cela semble pouvoir fonctionner, maintenant il y a l'Optimizer qui peut considérer que passer par la table initiale va plus vite...
Tu peux tenter de forcer le REWRITE avec un HINT.
Code : Sélectionner tout - Visualiser dans une fenêtre à part select /*+ REWRITE */ ...
ça marche toujours pas... auriez vous une autre idée??
Je ne suis pas spécialiste en QUERY REWRITE mais il se peut que ton CASE mette la grouille.
Tente la requête avec les éléments brut de force (A l'identique de ta vue matérialisée). ensuite par évolution change et teste ta requête afin d'arriver à tes fins.
Tu verras bien où ça bloque...
je l'ai fait, mais une fois que j'enlève n'importe quel champ du select ça marche plus![]()
Essai bête et méchant, si tu n'enlève aucun champs et que tu ne fais que rajouter (Il suffit de ne pas traiter ceux en trop), ça donne quoi ?
ça marche toujours pas, mais là ça peut se comprendre puisque le champ demandé n'est pas disponible dans la vue matérialisée.
En ce cas peux-tu déporter les éléments liés à ta vue matérialisée (select, from & where) dans une sous-requte ?
J'avais ma lu, il faut que TOUS tes champs de la table que tu veux bypasser soient dans la vue matérialisée...
Ici il te manque VOLM.
Tu as SUM(VOLM) et non VOLM. Oracle ne peut traduire que le VOLM d'une requête correspond à une pseudo colonne calculée dans une vue matérialisée.
oui vous avez raison mais faites attention au 'AS':
SUM(VOLM) AS "VOLM"
C'est bien ce que je dis, dans ton CASE tu checke la valeur de VOLM (La colonne) et dans ta vue matérialisée tu fourni un SUM(VOLM) (Et pas la colonne VOLM elle-même).
Donc, il est normal qu'il aille chercher la colonne VOLM dans la table, et le reste avec.
L'Oracle n'est ni un devin, ni un adepte des boules de crystal...
![]()
ok,
mais malgré cela ça marche pas, en fait, la requête de la vue matérialisée ne peut pas être réécrite, une fois qu'on enlève une colone du group by!!!
J'avais pas vu non lus, décidément, il faut effectivement que la vue matérialisée corresponde mathématiquement à une partie de ta requête. Si il faut triturer le résultat pour en sortir le besoin, elle ne sera pas prise en compte...
Partager