Tibar | Bonjour tout le monde,
J'ai un problème très étrange sous Oracle 9i : Objectif de la requête : Trouver la quantité vendue pour un article CARTICLE après une date donnée DDEB_ANALYSE_MNC pour les ventes ayant eu lieu en saison...
Pour faire plus clair, un petit axe de temps : Ma date de 1ère vente de l'article est au 05/04/2008
La date à partir de laquelle je souhaite analyser est le 01/02/2009 (cette date est calculée auparavant)
Année 2008
|--|--|--|*-|XX|XX|--|--|--|--|--|--|
* : date de première vente (05/04/2008)
XX représente une période en saison (ici, on est en saison du 01/05 au 30/06, quelque soit l'année)
Année 2009
|--|*-|--|--|XX|XX|--|--|--|--|--|--|
* : date de début d'analyse (01/02/2009)
XX représente une période en saison (ici, on est en saison du 01/05 au 30/06)
Année 2010
|--|--|--|--|XX|XX|--|--|--|--|--|--|
XX représente une période en saison (ici, on est en saison du 01/05 au 30/06)
Année 2011
|--|--|*-|--|XX|XX|--|--|--|--|--|--|
* : date de fin d'analyse : date du jour
XX représente une période en saison (ici, on est en saison du 01/05 au 30/06)
Pour ces calculs, j'ai donc : MJOUR_DEBUT_SAISON : jour de début de période de saison, valeur = 1
MMOIS_DEBUT_SAISON : mois de début de période de saison, valeur = 5
MJOUR_FIN_SAISON : jour de fin de période de saison, valeur = 30
MMOIS_FIN_SAISON : mois de fin de période de saison, valeur = 6
DDEB_ANALYSE_MNC : date à laquelle je commence à comptabiliser les ventes
TMODIFICATION : si il est à 2, la donnée est supprimée logiquement, on n'en tient pas compte
DMODIFICATION : date de la vente
QVENDUE : quantité vendue à une date (aggrégat quotidien)
Requête qui passe en environ 0,1 sec :
SELECT ASE.QVENDUE,
XBA.CARTICLE, ASE.DMODIFICATION,
XBA.DDEB_ANALYSE_MNC,
NMS.MJOUR_DEBUT_SAISON,
NMS.MMOIS_DEBUT_SAISON,
NMS.MJOUR_FIN_SAISON,
NMS.MMOIS_FIN_SAISON
FROM ARTICLE_SEMAINE ASE --contient les ventes aggrégées par jour
INNER JOIN XBA_TST XBA ON XBA.CARTICLE = ASE.CARTICLE --XBA_TST est ma table de test
INNER JOIN ARTICLE.NSAISON NMS ON NMS.CNMODULE = XBA.CNMODULE --NSAISON contient mes périodes de saison
AND NMS.TMODIFICATION <> 2 WHERE XBA.CARTICLE = 65286 --filtre pour test, je ne regarde qu'un article pour le moment
AND ASE.DMODIFICATION >= XBA.DDEB_ANALYSE_MNC --filtre pour date, je ne m'interesse qu'aux dates > DDEB_ANALYSE_MNC
--liste des critères pour qu'une vente soit en saison
--jour de vente >= jour de début de saison
AND to_number(to_char(ASE.DMODIFICATION, 'DD')) >= NMS.MJOUR_DEBUT_SAISON
--mois de vente >= mois de début de saison
AND to_number(to_char(ASE.DMODIFICATION, 'MM')) >= NMS.MMOIS_DEBUT_SAISON
--jour de vente <= jour de fin de saison
AND to_number(to_char(ASE.DMODIFICATION, 'DD')) <= NMS.MJOUR_FIN_SAISON
|
A ce stade, tout va bien, mais on remarque qu'il manque un critère, que je rajoute dans cette requête :
SELECT ASE.QVENDUE,
XBA.CARTICLE, ASE.DMODIFICATION,
XBA.DDEB_ANALYSE_MNC,
NMS.MJOUR_DEBUT_SAISON,
NMS.MMOIS_DEBUT_SAISON,
NMS.MJOUR_FIN_SAISON,
NMS.MMOIS_FIN_SAISON
FROM ARTICLE_SEMAINE ASE
INNER JOIN XBA_TST XBA ON XBA.CARTICLE = ASE.CARTICLE
INNER JOIN ARTICLE.NSAISON NMS ON NMS.CNMODULE = XBA.CNMODULE AND NMS.TMODIFICATION <> 2 WHERE XBA.CARTICLE = 65286
AND ASE.DMODIFICATION >= XBA.DDEB_ANALYSE_MNC --liste des critères pour qu'une vente soit en saison
--jour de vente >= jour de début de saison
AND to_number(to_char(ASE.DMODIFICATION, 'DD')) >= NMS.MJOUR_DEBUT_SAISON
--mois de vente >= mois de début de saison
AND to_number(to_char(ASE.DMODIFICATION, 'MM')) >= NMS.MMOIS_DEBUT_SAISON
--jour de vente <= jour de fin de saison
AND to_number(to_char(ASE.DMODIFICATION, 'DD')) <= NMS.MJOUR_FIN_SAISON --mois de vente <= mois de fin de saison
AND to_number(to_char(ASE.DMODIFICATION, 'MM')) <= NMS.MMOIS_FIN_SAISON --critère ajouté
|
et là, c'est le drame, ça ne répond plus (enfin, j'ai laissé tourner 1 min)... Je vous mets les explain plan des 2 requêtes : REQUETE 1, répond bien :
DESC OWNER NAME COST CARD BYTES
SELECT STATEMENT, GOAL = CHOOSE 177 1 61
MERGE JOIN 177 1 61
SORT JOIN 72 3 78
MERGE JOIN 65 3 78
SORT JOIN 51 21 273
TABLE ACCESS BY INDEX ROWIDAPPRO ARTICLE_SEMAINE 44 21 273
INDEX SKIP SCAN APPRO PK_ARTICLE_SEMAINE 24 21 FILTER SORT JOIN TABLE ACCESS FULL ARTICLE NSAISON 4 1004 13052
FILTER SORT JOIN TABLE ACCESS FULL APPRO XBA_TST 96 368 12880
|
REQUETE 2, ne répond pas :
DESC OWNER NAME COST CARD BYTES
SELECT STATEMENT, GOAL = CHOOSE 161 1 61
NESTED LOOPS 161 1 61
MERGE JOIN 65 1 26
SORT JOIN 51 21 273
TABLE ACCESS BY INDEX ROWID APPRO ARTICLE_SEMAINE 44 21 273
INDEX SKIP SCAN APPRO PK_ARTICLE_SEMAINE 24 21 FILTER SORT JOIN TABLE ACCESS FULL ARTICLE NSAISON 4 1004 13052
TABLE ACCESS FULL APPRO XBA_TST 96 1 35
|
Voila voila, ça m'intéresserait bien de comprendre pourquoi en ajoutant ce critère supplémentaire, mon explain plan change complètement et ma requête ne répond plus...
J'ai essayé en mettant le critère :
AND to_number(to_char(ASE.DMODIFICATION, 'MM')) <= NMS.MMOIS_FIN_SAISON --critère ajouté
avant les 3 autres critères de date, ça ne change rien...
(pour résumer, ce n'est pas CE crtitère qui pose problème, mais le fait que je rajoute un 4è critère)... |