[SGBD] Encore une requête à décorner les boeufs...

Encore une requête à décorner les boeufs... [SGBD] - SQL/NoSQL - Programmation

Marsh Posté le 02-02-2006 à 11:57:35    

... qui nécessite votre coup de main pour l'améliorer...
 
Toujours le même ERP, toujours la même base Oracle, toujours les mêmes tables [:atari]  
 
A savoir :
 
Table PRO produits
 
Index unique :
codsoc
codpro
 
Les autres champs :
sigdep dépôt principal
sigfou fournisseur principal
codblocage statut du produit
 
Table MVT mouvements de stock
 
Index unique :
codsoc
codpro
sigdep
numlot numéro de lot (oujours à ' ' ici)
nummvt numéro de mouvement (compteur autoincrément pour le quaruplet ci-dessus)
 
Index que je viens de créer :
codsoc
codpro
sigdep
datmvt date du mouvement
 
Champs utilisés
c01 stock physique
qteope quantité de l'oppération
codosk type d'opération de stock
 
Table OSK oppérations de stock
 
Index unique :
codsoc
codosk
 
Champs utilisés :
opec01 oppération à effectuer sur le compteur physique c01
 
Je dois retrouver :
1) Les quantités en stock avant inventaire
2) Les quantités inventoriées
3) Le cumul des entrées/sorties dans le stock physique depuis l'inventaire
 
Le tout :
- Sur une période donnée
- Il peut y avoir plusieurs inventaires sur la période
- Il peut ne pas y avoir d'inventaire sur la période
- Si le produit n'a pas bougé du tout dans la période, pas la peine de le retourner
- L'inventaire est reconnaissable dans la base par un CODOSK = 'INICPT' (initialisation des compteurs)
- Pour les oppérations de stock, dans la table OSK j'ai '+' ou '-' (ou ' ') dans la colonne OPEC01 afin d'indiquer pour le CODOSK si je dois ajouter ou supprimer le QTEOPE sur mon compteur physique c01
 
 
Voici la requête actuelle, pour tous les produits d'un fournisseur :

Code :
  1. select '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  2. from msk, pro
  3. where pro.codsoc = 2
  4. and pro.sigfou = 'HERITAGE'
  5. and msk.codsoc = pro.codsoc
  6. and msk.codpro = pro.codpro
  7. and msk.sigdep = pro.sigdep
  8. and msk.numlot = ' '
  9. and msk.nummsk =
  10. (select max(m1.nummsk)
  11. from msk m1
  12. where m1.codsoc = msk.codsoc
  13. and m1.codpro = msk.codpro
  14. and m1.sigdep = msk.sigdep
  15. and m1.numlot = ' '
  16. and m1.nummsk < (
  17. select max(m2.nummsk)
  18. from msk m2
  19. where m2.codsoc = m1.codsoc
  20. and m2.codpro = m1.codpro
  21. and m2.sigdep = m1.sigdep
  22. and m2.datmvt between '20051231' and '20060131'
  23. and m2.codosk = 'INICPT'
  24. ))
  25. union all
  26. select '2' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entreesapres, 0 sortiesapres, msk.c01 initinventaire, 0 avantinv
  27. from msk, pro
  28. where pro.codsoc = 2
  29. and pro.sigfou = 'HERITAGE'
  30. and msk.codsoc = pro.codsoc
  31. and msk.sigdep = pro.sigdep
  32. and msk.codpro = pro.codpro
  33. and msk.datmvt between '20051231' and '20060131'
  34. and msk.codosk = 'INICPT'
  35. union all
  36. select '3' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, sum(msk.qteope * decode(osk.opec01, '+', 1, 0)) entreesapres, sum(msk.qteope * decode(osk.opec01, '-', 1, 0)) sortiesapres, 0 initinventaire, 0 avantinv
  37. from osk, msk, pro
  38. where pro.codsoc = 2
  39. and pro.sigfou = 'HERITAGE'
  40. and msk.codsoc = pro.codsoc
  41. and msk.sigdep = pro.sigdep
  42. and msk.codpro = pro.codpro
  43. and msk.datmvt between '20051231' and '20060131'
  44. and osk.codsoc = msk.codsoc
  45. and osk.codosk = msk.codosk
  46. and
  47. (
  48.   msk.nummsk > (select max(nummsk) from msk m where m.codsoc = msk.codsoc and m.sigdep = msk.sigdep and m.codpro = msk.codpro and m.datmvt between '20051231' and '20060131' and m.codosk = 'INICPT')
  49.   or
  50.   not exists (select null from msk m where m.codsoc = msk.codsoc and m.sigdep = msk.sigdep and m.codpro = msk.codpro and m.datmvt between '20051231' and '20060131' and m.codosk = 'INICPT')
  51. )
  52. group by pro.sigfou, pro.codpro, pro.codblocage, msk.sigdep
  53. order by 2, 3, 4, 1


 
Ca marche, mais c'est assez lent : 1 minute. Je dois récupérer la même chose, mais pour TOUS les produits de la base, c'est à dire qu'en estimant à 1 minute par fournisseur, y'en a pour une demi-journée :D (enfin... plus d'une heure en tout cas ;))
 
Les parties 2 et 3 de ma requête sont rapides (4 secondes).
 
Par contre, c'est la première qui cloche (quand on voit sa tronche c'est un peu normal aussi)
 
Comment je pourrais l'améliorer ?
Pour rappel, cette partie recherche "la quantité dans le compteur c01 lors du dernier mouvement de stock avant le dernier inventaire de la période"

Code :
  1. select '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  2. from msk, pro
  3. where pro.codsoc = 2
  4. and pro.sigfou = 'HERITAGE'
  5. and msk.codsoc = pro.codsoc
  6. and msk.codpro = pro.codpro
  7. and msk.sigdep = pro.sigdep
  8. and msk.numlot = ' '
  9. and msk.nummsk =
  10. (select max(m1.nummsk)
  11. from msk m1
  12. where m1.codsoc = msk.codsoc
  13. and m1.codpro = msk.codpro
  14. and m1.sigdep = msk.sigdep
  15. and m1.numlot = ' '
  16. and m1.nummsk < (
  17. select max(m2.nummsk)
  18. from msk m2
  19. where m2.codsoc = m1.codsoc
  20. and m2.codpro = m1.codpro
  21. and m2.sigdep = m1.sigdep
  22. and m2.datmvt between '20051231' and '20060131'
  23. and m2.codosk = 'INICPT'
  24. ))


 
:sweat:


Message édité par Arjuna le 02-02-2006 à 11:58:56
Reply

Marsh Posté le 02-02-2006 à 11:57:35   

Reply

Marsh Posté le 02-02-2006 à 12:08:41    

Reuh...
 
J'ai divisé le temps par deux en ajoutant cet index :
 

Code :
  1. CREATE INDEX MSK_WI_IDX2 ON MSK
  2. (CODSOC, CODPRO, SIGDEP, CODOSK)
  3. LOGGING
  4. TABLESPACE IDXGNX1
  5. PCTFREE    10
  6. INITRANS   2
  7. MAXTRANS   255
  8. STORAGE    (
  9.             INITIAL          24K
  10.             NEXT             7000K
  11.             MINEXTENTS       1
  12.             MAXEXTENTS       120
  13.             PCTINCREASE      10
  14.             FREELISTS        1
  15.             FREELIST GROUPS  1
  16.             BUFFER_POOL      DEFAULT
  17.            )
  18. NOPARALLEL;


 
Mais ça m'emmerde... Les deux derniers UNION durent 700ms seulement... Alors que le premier bout dure 16 seconds à lui tout seul :(

Reply

Marsh Posté le 02-02-2006 à 12:42:51    

mé heu :sweat:
 
pkoi y'a jamais personne qui me répond quand c'est chez moi que ça marche pas ? :cry:

Reply

Marsh Posté le 02-02-2006 à 12:48:13    

Arjuna a écrit :

mé heu :sweat:
 
pkoi y'a jamais personne qui me répond quand c'est chez moi que ça marche pas ? :cry:


 
T'as vu la tête de ta première requete? :D

Reply

Marsh Posté le 02-02-2006 à 12:59:05    

tu sais montrer l'execution plan?

Reply

Marsh Posté le 02-02-2006 à 13:14:29    

casimimir a écrit :

tu sais montrer l'execution plan?


 
Il n'y en a pas besoin pour voir que 3 requêtes imbriquées donnent de mauvaises perfs (même avec tout les indexs qui vont bien). Il faufrait plutot chercher du côté de la simplification de la requête.

Message cité 1 fois
Message édité par thecoin le 02-02-2006 à 13:14:40
Reply

Marsh Posté le 02-02-2006 à 13:58:33    

rappel :  
 

Code :
  1. SELECT col1,max(col2)
  2. FROM...
  3. GROUP BY col1


 
Equivaut à :

Code :
  1. SELECT col1,col2
  2. FROM...
  3. WHERE col2 = (SELECT max(col2) FROM ... WHERE col2=col2


 
Essaye de voir si c'est pas jouable.
 
Sinon, tu peux peut-être t'en sortir avec GREATEST ou la fonction analytique MAX ;) -> http://lalystar.developpez.com/fon [...] ques/#L3.4

Reply

Marsh Posté le 02-02-2006 à 14:24:32    

ben pas du tout pour le coup des select.
le premier rammène la valeur maximale de col2 pour chaque valeur de col1, tandis que le second ramène la valeur de col1 pour laquelle col2 est maximale, c'est pas du tout pareil.
 
pour le reste, j'essaie de comprendre ces fonctions que je ne connais pas du tout !

Reply

Marsh Posté le 02-02-2006 à 14:36:54    

casimimir a écrit :

tu sais montrer l'execution plan?


J'arrive pas à l'activer avec Toad. Je suis pourtant en SYSTEM et j'ai lancé toadprep, mais pas moyen.

Reply

Marsh Posté le 02-02-2006 à 14:37:17    

thecoin a écrit :

Il n'y en a pas besoin pour voir que 3 requêtes imbriquées donnent de mauvaises perfs (même avec tout les indexs qui vont bien). Il faufrait plutot chercher du côté de la simplification de la requête.


je suis d'accord sur ce point

Reply

Marsh Posté le 02-02-2006 à 14:37:17   

Reply

Marsh Posté le 02-02-2006 à 14:43:15    

pffff, j'ai trop bouffé, j'ai le cerveau en compote, j'arrive plus à réfléchir :sweat:

Reply

Marsh Posté le 02-02-2006 à 14:48:25    

je ne suis pas d'accord, au moins on saurait pour quelle partie le cout est le plus élevé et voir ou adapter, que ce soit en réécrivant le select ou en créant un index utile.

Reply

Marsh Posté le 02-02-2006 à 14:50:04    

Tu pourrais pas donner les scripts pour créer les tables ?
Ca permettrait à ceux qui veulet plancher dessus de le faire plus facilement :D (moi par exemple ;) ).
 
Il faudrait les CREATE TABLE, CREATE INDEX, et puis même si possible quelques données ...
 
edit :
 
à la va-vite (probablement des erreurs :D ), j'ai mis le dernier sous-select dans le FROM, et j'ai changé le '= SELECT MAX()' en ORDER BY DESC avec ROWNUM = 1.
Etant donné que je n'ai pas accès aux données, c'est pas évident de vérifier si le résultat est correct, en tout cas je pense que ce sont des pistes à explorer, en particulier si tu dois ensuite faire la même chose pour tous les produits (faut factoriser au maximum ;) )  :
 

Code :
  1. SELECT * FROM (
  2. SELECT '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  3. FROM msk, pro,
  4.      (SELECT codsoc, codpro, sigdep, MAX(m2.nummsk) AS max_nummsk
  5.       FROM msk m2
  6.       WHERE m2.datmvt BETWEEN '20051231' AND '20060131'
  7.       AND m2.codosk = 'INICPT') sub
  8. WHERE pro.codsoc = 2
  9. AND pro.sigfou = 'HERITAGE'
  10. AND msk.codsoc = pro.codsoc
  11. AND msk.codpro = pro.codpro
  12. AND msk.sigdep = pro.sigdep
  13. AND msk.numlot = ' '
  14. AND sub.codsoc = msk.codsoc
  15. AND sub.codpro = msk.codpro
  16. AND sub.sigdep = msk.sigdep
  17. AND msk.nummsk < sub.max_nummsk
  18. ORDER BY msk.nummsk DESC)
  19. WHERE ROWNUM = 1;


 
edit 2 : en gros j'ai appliqué une fois ce qu'orafrance proposait ... même si je ne l'ai lu qu'après :D


Message édité par Beegee le 02-02-2006 à 15:03:34
Reply

Marsh Posté le 02-02-2006 à 15:01:19    

Arjuna a écrit :


le premier rammène la valeur maximale de col2 pour chaque valeur de col1, tandis que le second ramène la valeur de col1 pour laquelle col2 est maximale, c'est pas du tout pareil.


 
relis ta phrase... c'est la même chose :/
 
1°) raméne le col1 et max(col2)
2°) raméne col1 et col2 ou col2=max(col2) -> col1 et max(col2)
 
Fait un test si t'es pas convaincu ;)

Reply

Marsh Posté le 02-02-2006 à 15:32:03    

orafrance > ton truc ne marche que si on faut un rownum = 1 dans la requête, sinon il me ramène plein de lignes que je ne veux pas.
 
beegee > a vue de nez, ta requête est largement pire que la mienne :D 1:45 pour retrouver une ligne (normalement je dois avoir 124 lignes :D) :sweat:
vais voir ce qui déconne avant de déclarer qu'elle est plus lente, parceque le fait de pas rammener ce qu'il faut fausse pas mal le résultat je pense ;)
 
Sinon, voici la structure des tables : (tu vas voir que tu préférais quand t'avais pas l'info ;))
 
 

Code :
  1. CREATE TABLE PRO
  2. (
  3.   CODPRO      VARCHAR2(16),
  4.   MOTCLE      VARCHAR2(16),
  5.   FAMPRO      VARCHAR2(6),
  6.   SFAPRO      VARCHAR2(6),
  7.   SSFPRO      VARCHAR2(6),
  8.   NOMPRO      VARCHAR2(30),
  9.   GENCOD      VARCHAR2(13),
  10.   CODDOU      VARCHAR2(16),
  11.   TYPPRO      VARCHAR2(3),
  12.   EXICOT      VARCHAR2(1),
  13.   CODTVA      VARCHAR2(1),
  14.   CODUNI      VARCHAR2(3),
  15.   QTEMIN      NUMBER,
  16.   CODTAX      VARCHAR2(1),
  17.   CODTAX2     VARCHAR2(1),
  18.   SIGDEP      VARCHAR2(12),
  19.   CODREA      VARCHAR2(6),
  20.   SUISTK      VARCHAR2(1),
  21.   PROSTK      VARCHAR2(16),
  22.   DELPRE      INTEGER,
  23.   SUISTT      VARCHAR2(1),
  24.   CLAABC      VARCHAR2(1),
  25.   DATMAR      VARCHAR2(8),
  26.   POIDS       NUMBER,
  27.   HAUTE       NUMBER,
  28.   LARGE       NUMBER,
  29.   LONGUE      NUMBER,
  30.   VOLUME      NUMBER,
  31.   CODTAR      VARCHAR2(16),
  32.   DESIGN1     VARCHAR2(40),
  33.   DESIGN2     VARCHAR2(40),
  34.   DESIGN3     VARCHAR2(40),
  35.   TYPTAR      VARCHAR2(3),
  36.   SIGFOU      VARCHAR2(12),
  37.   DATMOD      VARCHAR2(8),
  38.   UTIMOD      VARCHAR2(8),
  39.   REFPRO      VARCHAR2(16),
  40.   NUMVAR      INTEGER,
  41.   TPSMON      INTEGER,
  42.   INDCOM      VARCHAR2(1),
  43.   VA          VARCHAR2(2),
  44.   VL          VARCHAR2(2),
  45.   CODUVC      VARCHAR2(3),
  46.   CODUE       VARCHAR2(3),
  47.   NBUCUE      INTEGER,
  48.   PCB         INTEGER,
  49.   UNIPCB      VARCHAR2(3),
  50.   SPCB        INTEGER,
  51.   UNISPCB     VARCHAR2(3),
  52.   CODZN1      VARCHAR2(12),
  53.   CODZN2      VARCHAR2(12),
  54.   CODZN3      VARCHAR2(12),
  55.   CODZN4      VARCHAR2(12),
  56.   CODZN5      VARCHAR2(12),
  57.   CODZN6      VARCHAR2(12),
  58.   CODZN7      VARCHAR2(12),
  59.   CODZN8      VARCHAR2(12),
  60.   CODZN9      VARCHAR2(12),
  61.   CODZN10     VARCHAR2(12),
  62.   CODZN11     VARCHAR2(12),
  63.   CODZN12     VARCHAR2(12),
  64.   CODZN13     VARCHAR2(12),
  65.   CODZN14     VARCHAR2(12),
  66.   CODZN15     VARCHAR2(12),
  67.   CODZN16     VARCHAR2(12),
  68.   UNICOL      VARCHAR2(3),
  69.   COLEC1      VARCHAR2(1),
  70.   STCK1       INTEGER,
  71.   COLEC2      VARCHAR2(1),
  72.   STCK2       INTEGER,
  73.   COLEC3      VARCHAR2(1),
  74.   STCK3       INTEGER,
  75.   COLEC4      VARCHAR2(1),
  76.   STCK4       INTEGER,
  77.   COLEC5      VARCHAR2(1),
  78.   STCK5       INTEGER,
  79.   COLEC6      VARCHAR2(1),
  80.   STCK6       INTEGER,
  81.   COLEC7      VARCHAR2(1),
  82.   STCK7       INTEGER,
  83.   COLEC8      VARCHAR2(1),
  84.   STCK8       INTEGER,
  85.   COLEC9      VARCHAR2(1),
  86.   STCK9       INTEGER,
  87.   DESIGN4     VARCHAR2(40),
  88.   DESIGN5     VARCHAR2(40),
  89.   DESIGN6     VARCHAR2(40),
  90.   DESIGN7     VARCHAR2(40),
  91.   DESIGN8     VARCHAR2(40),
  92.   DESIGN9     VARCHAR2(40),
  93.   DESIGN10    VARCHAR2(40),
  94.   DESIGN11    VARCHAR2(40),
  95.   DESIGN12    VARCHAR2(40),
  96.   CODDEV      VARCHAR2(3),
  97.   CODBLOCAGE  VARCHAR2(3),
  98.   POIDSNET    NUMBER,
  99.   TYPAFF      VARCHAR2(6),
  100.   QOTITE      NUMBER,
  101.   UNISTA      VARCHAR2(3),
  102.   PROSTA      VARCHAR2(16),
  103.   INDCTS      VARCHAR2(1),
  104.   INDRIS      VARCHAR2(1),
  105.   VALPVR      NUMBER,
  106.   PDSPVR      NUMBER,
  107.   VOLPVR      NUMBER,
  108.   NUMLSK      INTEGER,
  109.   CODSOC      INTEGER,
  110.   DELREA      INTEGER,
  111.   DATCRE      VARCHAR2(8),
  112.   ETBCOD      VARCHAR2(3),
  113.   ETSSTATUT   VARCHAR2(1),
  114.   CODCONV     VARCHAR2(3),
  115.   CLAABCP     VARCHAR2(1),
  116.   DELPER      INTEGER,
  117.   SUIINS      VARCHAR2(1),
  118.   SUIICE      VARCHAR2(1),
  119.   NOMISE      VARCHAR2(1),
  120.   UNIICE      VARCHAR2(3),
  121.   TYPIFA      VARCHAR2(1),
  122.   UNIPER      VARCHAR2(3),
  123.   DELGAR      INTEGER,
  124.   UNIGAR      VARCHAR2(3),
  125.   ACHICE      VARCHAR2(1),
  126.   TYPICE      VARCHAR2(3),
  127.   SIGICE      VARCHAR2(12),
  128.   VERICE      INTEGER,
  129.   PRORUB      VARCHAR2(16),
  130.   TEECOD      VARCHAR2(1),
  131.   TEEUNI      VARCHAR2(3),
  132.   TEEPRX      NUMBER,
  133.   MODLOT      VARCHAR2(1),
  134.   CODPAY      VARCHAR2(3),
  135.   TTAICE      VARCHAR2(3),
  136.   CODMDL      VARCHAR2(6),
  137.   PROREF      VARCHAR2(16),
  138.   SUIREF      VARCHAR2(1),
  139.   REPART      NUMBER,
  140.   CODUNIC     VARCHAR2(60),
  141.   TYPREF      VARCHAR2(6),
  142.   DATFINMAR   VARCHAR2(8)
  143. )
  144. TABLESPACE DATGNX1
  145. PCTUSED    40
  146. PCTFREE    10
  147. INITRANS   1
  148. MAXTRANS   255
  149. STORAGE    (
  150.             INITIAL          32K
  151.             NEXT             1816K
  152.             MINEXTENTS       1
  153.             MAXEXTENTS       120
  154.             PCTINCREASE      10
  155.             FREELISTS        1
  156.             FREELIST GROUPS  1
  157.             BUFFER_POOL      DEFAULT
  158.            )
  159. LOGGING
  160. NOCACHE
  161. NOPARALLEL;
  162. CREATE UNIQUE INDEX PRO_IDX1 ON PRO
  163. (CODSOC, CODPRO)
  164. LOGGING
  165. TABLESPACE IDXGNX1
  166. PCTFREE    10
  167. INITRANS   2
  168. MAXTRANS   255
  169. STORAGE    (
  170.             INITIAL          24K
  171.             NEXT             168K
  172.             MINEXTENTS       1
  173.             MAXEXTENTS       120
  174.             PCTINCREASE      10
  175.             FREELISTS        1
  176.             FREELIST GROUPS  1
  177.             BUFFER_POOL      DEFAULT
  178.            )
  179. NOPARALLEL;
  180. CREATE INDEX PRO_IDX9 ON PRO
  181. (CODSOC, GENCOD)
  182. LOGGING
  183. TABLESPACE IDXGNX1
  184. PCTFREE    10
  185. INITRANS   2
  186. MAXTRANS   255
  187. STORAGE    (
  188.             INITIAL          24K
  189.             NEXT             240K
  190.             MINEXTENTS       1
  191.             MAXEXTENTS       120
  192.             PCTINCREASE      10
  193.             FREELISTS        1
  194.             FREELIST GROUPS  1
  195.             BUFFER_POOL      DEFAULT
  196.            )
  197. NOPARALLEL;
  198. CREATE INDEX PRO_WEB_IX1 ON PRO
  199. (CODSOC, SIGFOU, FAMPRO, SSFPRO, SUISTK,
  200. CODBLOCAGE)
  201. LOGGING
  202. TABLESPACE IDXGNX1
  203. PCTFREE    10
  204. INITRANS   2
  205. MAXTRANS   255
  206. STORAGE    (
  207.             INITIAL          24K
  208.             NEXT             55M
  209.             MINEXTENTS       1
  210.             MAXEXTENTS       2147483645
  211.             PCTINCREASE      10
  212.             FREELISTS        1
  213.             FREELIST GROUPS  1
  214.             BUFFER_POOL      DEFAULT
  215.            )
  216. NOPARALLEL;
  217. CREATE INDEX WI_PRO ON PRO
  218. (CODSOC, SIGFOU)
  219. LOGGING
  220. TABLESPACE IDXGNX1
  221. PCTFREE    10
  222. INITRANS   2
  223. MAXTRANS   255
  224. STORAGE    (
  225.             INITIAL          24K
  226.             NEXT             192K
  227.             MINEXTENTS       1
  228.             MAXEXTENTS       120
  229.             PCTINCREASE      10
  230.             FREELISTS        1
  231.             FREELIST GROUPS  1
  232.             BUFFER_POOL      DEFAULT
  233.            )
  234. NOPARALLEL;
  235. CREATE INDEX WI_PROZN15 ON PRO
  236. (CODSOC, CODZN15)
  237. LOGGING
  238. TABLESPACE IDXGNX1
  239. PCTFREE    10
  240. INITRANS   2
  241. MAXTRANS   255
  242. STORAGE    (
  243.             INITIAL          24K
  244.             NEXT             264K
  245.             MINEXTENTS       1
  246.             MAXEXTENTS       120
  247.             PCTINCREASE      10
  248.             FREELISTS        1
  249.             FREELIST GROUPS  1
  250.             BUFFER_POOL      DEFAULT
  251.            )
  252. NOPARALLEL;
  253. CREATE OR REPLACE TRIGGER "MAJ_PRO" AFTER INSERT OR UPDATE OF "CODPRO", "CODSOC", "CODZN2", "SIGFOU", "VOLUME" ON "SOC1"."PRO" FOR EACH ROW
  254. WHEN (
  255. nvl(old.codzn2,0)<>new.codzn2 or old.volume<>new.volume and new.codsoc<>3
  256.       )
  257. declare
  258. cursor frn is
  259.   select coddev,decode(codzn1,' ','0',codzn1) codzn1,
  260.          replace(decode(codzn2,' ','0',codzn2),',','.') codzn2
  261.     from tie
  262.    where sigtie=:new.sigfou and typtie='FOU' and codsoc=:new.codsoc;
  263. codev     varchar2(6);
  264. dadev     varchar2(30);
  265. txdev     number(18,6);
  266. cdzn      varchar2(12);
  267. pxach     number;
  268. frapp     number;
  269. pxrev     number;
  270. coefmg    number:=2.2;
  271. pxvenc    number;
  272. pxven     number;
  273. mrgval    number;
  274. mrgpct    number;
  275. dev_abs   varchar2(2):='NK';
  276. begin
  277.   for f in frn loop
  278.   begin
  279.     select cours into txdev from dem
  280.      where codsoc=:new.codsoc and coddev=f.coddev and natdev='PRE' and
  281.              (datdeb,datfin) = (select max(datdeb), datfin from dem
  282.                                  where codsoc=:new.codsoc and coddev=f.coddev and
  283.                                        natdev='PRE' and datdeb<=to_char(sysdate,'yyyymmdd') and
  284.                                        nvl(datfin,'29991231')<=to_char(sysdate,'yyyymmdd')
  285.                                  group by datfin
  286.                                  having max(datdeb)<=to_char(sysdate,'yyyymmdd'));
  287.   exception
  288.     when no_data_found then txdev:=1;
  289.   end;
  290.    if :new.codzn2=' ' /* px achat obligatoire */
  291.     then cdzn:='1';
  292.     else cdzn:=:new.codzn2;
  293.    end if;
  294.     pxach:=to_number(replace(cdzn,',','.'))*to_number(txdev);
  295.       if (f.codzn1=0 and f.codzn2=0)
  296.        then frapp:=0;
  297.        else if f.codzn2=0    /* val au m3 par defaut sinon %VM */
  298.              then frapp:=to_number(f.codzn1)*pxach/100;
  299.              else frapp:=to_number(f.codzn2)*:new.volume;
  300.             end if;
  301.        end if;
  302.     pxrev:=pxach+frapp;
  303.     pxvenc:=pxrev*coefmg; /* que pour insertion */
  304.     mrgval:=pxvenc-pxrev;
  305.     if pxvenc<>0
  306.      then mrgpct:=mrgval/pxvenc; /*/100;*/
  307.      else mrgpct:=mrgval;
  308.     end if;
  309.     begin
  310.       select px_vent into pxven
  311.         from wt_prdwr_art
  312.        where co_art=:new.codpro and co_soc=:new.codsoc and co_dev=f.coddev;
  313. /*      mrgval:=pxvenc-pxrev;
  314.       if pxvenc<>0
  315.        then mrgpct:=mrgval/pxvenc;  
  316.        else mrgpct:=mrgval;
  317.       end if;
  318.       if pxrev<>0
  319.        then coefmg:=pxvenc/pxrev;
  320.        else coefmg:=pxvenc;
  321.       end if;
  322.       coef_mrg=coefmg, */
  323.       update wt_prdwr_art set px_acht=pxach, fr_apprt=frapp, px_revt=pxrev,
  324.                               mrg_valt=mrgval, mrg_prctgt=mrgpct,
  325.                               da_modif=sysdate, tx_dev=txdev, px_vent=pxvenc
  326.        where co_art=:new.codpro and co_soc=:new.codsoc and co_dev=f.coddev;
  327.     exception
  328.       when no_data_found then
  329.         insert into wt_prdwr_art
  330.          values (:new.codsoc, :new.codpro, f.coddev, txdev,  pxach, frapp, pxrev, coefmg,
  331.                  pxvenc, mrgval, mrgpct, sysdate,sysdate);
  332.     end;
  333.   end loop;
  334. exception
  335.   when no_data_found then null;
  336. end;
  337. /
  338. SHOW ERRORS;
  339. CREATE TABLE MSK
  340. (
  341.   SIGDEP  VARCHAR2(12),
  342.   CODPRO  VARCHAR2(16),
  343.   NUMLOT  VARCHAR2(7),
  344.   NUMMSK  INTEGER,
  345.   NUMPER  INTEGER,
  346.   DATMVT  VARCHAR2(8),
  347.   HEUMVT  NUMBER,
  348.   DATPRV  VARCHAR2(8),
  349.   CODOSK  VARCHAR2(6),
  350.   CODEMP  VARCHAR2(10),
  351.   ACHVTE  VARCHAR2(1),
  352.   TYPEVE  VARCHAR2(3),
  353.   NUMEVE  INTEGER,
  354.   POSEVE  INTEGER,
  355.   LIGEVE  INTEGER,
  356.   QTEOPE  NUMBER,
  357.   QTEMVT  NUMBER,
  358.   PRXVTE  NUMBER,
  359.   DPA     NUMBER,
  360.   PUMP    NUMBER,
  361.   DECOTE  NUMBER,
  362.   C01     NUMBER,
  363.   C02     NUMBER,
  364.   C03     NUMBER,
  365.   C04     NUMBER,
  366.   C05     NUMBER,
  367.   C06     NUMBER,
  368.   C07     NUMBER,
  369.   C08     NUMBER,
  370.   C09     NUMBER,
  371.   C10     NUMBER,
  372.   C11     NUMBER,
  373.   C12     NUMBER,
  374.   C13     NUMBER,
  375.   C14     NUMBER,
  376.   CODUNI  VARCHAR2(3),
  377.   UNIFAC  VARCHAR2(3),
  378.   DATMOD  VARCHAR2(8),
  379.   UTIMOD  VARCHAR2(8),
  380.   TYPOSK  VARCHAR2(3),
  381.   NUMDEB  VARCHAR2(12),
  382.   NUMFIN  VARCHAR2(12),
  383.   PRXREV  NUMBER,
  384.   CODSOC  INTEGER,
  385.   NUMOF   VARCHAR2(10),
  386.   LIBMSK  VARCHAR2(30),
  387.   INDTRT  VARCHAR2(1),
  388.   INDCES  VARCHAR2(1),
  389.   CODFCT  VARCHAR2(8),
  390.   CODPEV  VARCHAR2(8)
  391. )
  392. TABLESPACE DATGNX1
  393. PCTUSED    40
  394. PCTFREE    10
  395. INITRANS   1
  396. MAXTRANS   255
  397. STORAGE    (
  398.             INITIAL          32K
  399.             NEXT             15048K
  400.             MINEXTENTS       1
  401.             MAXEXTENTS       120
  402.             PCTINCREASE      10
  403.             FREELISTS        1
  404.             FREELIST GROUPS  1
  405.             BUFFER_POOL      DEFAULT
  406.            )
  407. LOGGING
  408. NOCACHE
  409. NOPARALLEL;
  410. CREATE UNIQUE INDEX MSK_IDX1 ON MSK
  411. (CODSOC, CODPRO, SIGDEP, NUMLOT, NUMMSK)
  412. LOGGING
  413. TABLESPACE IDXGNX1
  414. PCTFREE    10
  415. INITRANS   2
  416. MAXTRANS   255
  417. STORAGE    (
  418.             INITIAL          24K
  419.             NEXT             3928K
  420.             MINEXTENTS       1
  421.             MAXEXTENTS       120
  422.             PCTINCREASE      10
  423.             FREELISTS        1
  424.             FREELIST GROUPS  1
  425.             BUFFER_POOL      DEFAULT
  426.            )
  427. NOPARALLEL;
  428. CREATE INDEX MSK_WI_IDX1 ON MSK
  429. (CODSOC, CODPRO, SIGDEP, DATMVT)
  430. LOGGING
  431. TABLESPACE IDXGNX1
  432. PCTFREE    10
  433. INITRANS   2
  434. MAXTRANS   255
  435. STORAGE    (
  436.             INITIAL          24K
  437.             NEXT             7000K
  438.             MINEXTENTS       1
  439.             MAXEXTENTS       120
  440.             PCTINCREASE      10
  441.             FREELISTS        1
  442.             FREELIST GROUPS  1
  443.             BUFFER_POOL      DEFAULT
  444.            )
  445. NOPARALLEL;
  446. CREATE INDEX MSK_WI_IDX2 ON MSK
  447. (CODSOC, CODPRO, SIGDEP, CODOSK)
  448. LOGGING
  449. TABLESPACE IDXGNX1
  450. PCTFREE    10
  451. INITRANS   2
  452. MAXTRANS   255
  453. STORAGE    (
  454.             INITIAL          24K
  455.             NEXT             10264K
  456.             MINEXTENTS       1
  457.             MAXEXTENTS       120
  458.             PCTINCREASE      10
  459.             FREELISTS        1
  460.             FREELIST GROUPS  1
  461.             BUFFER_POOL      DEFAULT
  462.            )
  463. NOPARALLEL;
  464. CREATE TABLE OSK
  465. (
  466.   CODOSK     VARCHAR2(6),
  467.   LIBOSK     VARCHAR2(30),
  468.   LIROSK     VARCHAR2(10),
  469.   OPEC01     VARCHAR2(1),
  470.   OPEC02     VARCHAR2(1),
  471.   OPEC03     VARCHAR2(1),
  472.   OPEC04     VARCHAR2(1),
  473.   OPEC05     VARCHAR2(1),
  474.   OPEC06     VARCHAR2(1),
  475.   OPEC07     VARCHAR2(1),
  476.   OPEC08     VARCHAR2(1),
  477.   OPEC09     VARCHAR2(1),
  478.   OPEC10     VARCHAR2(1),
  479.   OPEC11     VARCHAR2(1),
  480.   OPEC12     VARCHAR2(1),
  481.   OPEC13     VARCHAR2(1),
  482.   OPEC14     VARCHAR2(1),
  483.   PRVC01     VARCHAR2(1),
  484.   PRVC02     VARCHAR2(1),
  485.   PRVC03     VARCHAR2(1),
  486.   PRVC04     VARCHAR2(1),
  487.   PRVC05     VARCHAR2(1),
  488.   PRVC06     VARCHAR2(1),
  489.   PRVC07     VARCHAR2(1),
  490.   PRVC08     VARCHAR2(1),
  491.   PRVC09     VARCHAR2(1),
  492.   PRVC10     VARCHAR2(1),
  493.   PRVC11     VARCHAR2(1),
  494.   PRVC12     VARCHAR2(1),
  495.   PRVC13     VARCHAR2(1),
  496.   PRVC14     VARCHAR2(1),
  497.   LOTOBL     VARCHAR2(1),
  498.   CALPMP     VARCHAR2(1),
  499.   OPEMAN     VARCHAR2(1),
  500.   TYPEVE     VARCHAR2(3),
  501.   CSKTE1     VARCHAR2(6),
  502.   OPETST     VARCHAR2(2),
  503.   CSKTE2     VARCHAR2(6),
  504.   OPEQT1     VARCHAR2(1),
  505.   CSKQT1     VARCHAR2(6),
  506.   OPEQT2     VARCHAR2(1),
  507.   CSKQT2     VARCHAR2(6),
  508.   OPEQT3     VARCHAR2(1),
  509.   CSKQT3     VARCHAR2(6),
  510.   CSKSUI     VARCHAR2(6),
  511.   OPESU1     VARCHAR2(1),
  512.   CSKSU1     VARCHAR2(6),
  513.   OPESU2     VARCHAR2(1),
  514.   CSKSU2     VARCHAR2(6),
  515.   OPESU3     VARCHAR2(1),
  516.   CSKSU3     VARCHAR2(6),
  517.   TYPOSK     VARCHAR2(3),
  518.   DATMOD     VARCHAR2(8),
  519.   UTIMOD     VARCHAR2(8),
  520.   TYPCTR     VARCHAR2(1),
  521.   EMPLOBL    VARCHAR2(1),
  522.   MAJINV     VARCHAR2(1),
  523.   GENMSK     VARCHAR2(1),
  524.   SEROBL     VARCHAR2(1),
  525.   CODSOC     INTEGER,
  526.   CODCSK     VARCHAR2(6),
  527.   OPECSK     VARCHAR2(1),
  528.   CODUT_MES  VARCHAR2(10),
  529.   PROPRIETE  VARCHAR2(1)
  530. )
  531. TABLESPACE DATGNX1
  532. PCTUSED    40
  533. PCTFREE    10
  534. INITRANS   1
  535. MAXTRANS   255
  536. STORAGE    (
  537.             INITIAL          32K
  538.             NEXT             560K
  539.             MINEXTENTS       1
  540.             MAXEXTENTS       120
  541.             PCTINCREASE      10
  542.             FREELISTS        1
  543.             FREELIST GROUPS  1
  544.             BUFFER_POOL      DEFAULT
  545.            )
  546. LOGGING
  547. NOCACHE
  548. NOPARALLEL;
  549. CREATE UNIQUE INDEX OSK_IDX1 ON OSK
  550. (CODSOC, CODOSK)
  551. LOGGING
  552. TABLESPACE IDXGNX1
  553. PCTFREE    10
  554. INITRANS   2
  555. MAXTRANS   255
  556. STORAGE    (
  557.             INITIAL          24K
  558.             NEXT             64K
  559.             MINEXTENTS       1
  560.             MAXEXTENTS       120
  561.             PCTINCREASE      10
  562.             FREELISTS        1
  563.             FREELIST GROUPS  1
  564.             BUFFER_POOL      DEFAULT
  565.            )
  566. NOPARALLEL;


 
Je sais pas si ça t'aide beaucoup :ange:
 
Pour les données, impossible pour deux raisons :
1/ Y'en a trop
2/ Vu que ça concerne les stocks, la valorisation et les fournisseurs d'une chaîne de magasins, c'est strictement confidentiel...
 
Mais je peux te donner la volumétrie :
 
PRO : 24464 lignes (3248 pour codsoc = 2)
OSK : 555 lignes (96 pour codsoc = 2)
MSK : (aïe) 664057 lignes (645915 pour codsoc = 2) et (28776 lignes pour codsoc = 2 et datmvt between '20051231' and '20060131')

Reply

Marsh Posté le 02-02-2006 à 15:43:57    

En fait, j'arrive pas à réécrire à la sauce orafrance/begee.
 
En français, le bout de requête qui merde ça donne :
 
Je veux récupérer, pour chaque produit du fournisseur "heritage" dans la société 2 la quantité de stock physique lors du dernier mouvement de stock avant la réinitialisation du compteur par les valeurs de l'inventaire le plus récent dans la période du 31/12/2005 au 31/01/2006
 
déjà, rien que pour comprendre ce que je veux, ça laisse rêveur [:atari]  
 
pour chaque produit du fournisseur "heritage" dans la société 2
=> pro.codsoc = 2 and pro.sigfou = 'HERITAGE'
 
quantité de stock physique
=> msk.c01
 
lors du dernier mouvement de stock
=> max(m1.nummsk) where m1.nummsk < m2.nummsk*
 
la réinitialisation du compteur par les valeurs de l'inventaire le plus récent
=> max(nummsk) where codosk = 'INICPT' (c'est le "m2.nummsk" de la ligne ci-dessus)
 
dans la période du 31/12/2005 au 31/01/2006
=> datmvt between '20051231' and '20060131'
 
et du coup j'arrive pas à faire autrement que mes deux sous-requêtes imbriquées

Message cité 1 fois
Message édité par Arjuna le 02-02-2006 à 15:47:30
Reply

Marsh Posté le 02-02-2006 à 15:54:41    

En fait, c'est un emmerdeur à la finance qui a eu peur en voyant un état merdé du stock (problème d'unité de colisage dans la valorisation du stock) et qui a failli avoir une crise cardiaque en voyant 700 000 € de différence ente la valeur du stock avant et après inventaire.
 
Et vu que ce financier est le directeur de la société financière qui a racheté la majorité des parts de la société, ben si il fait un caca nerveurx, faut dire "amen".
 
Et à cause de la pouff qui a fait un lot de "50000" enveloppes qu'elle a colisé par "1" dans la base et à donc multiplié le prix de ses 1000 colis d'enveloppes par 50000, il n'a plus confiance dans l'inventaire et les mouvements de stock qu'il y a eu depuis.
 
Alors le caca nerveux c'est :
 
Pour tous les produits de tous les fournisseurs :
quantité avant inventaire
quantité inventoriée
quantité régulée (réinventaire)
total des sorties depuis
total des entrées depuis
 
afin de comparer avec les stocks de la base, et un recomptage qu'il a ordonné de faire par une société externe :o
 
perso, bibi il préfèrerait aller re-compter les enveloppes au dépôt plutôt que de se griller ce qui lui reste de neuronnes sur sa requête à la mord-moi-le-noeud :sweat:


Message édité par Arjuna le 02-02-2006 à 15:55:30
Reply

Marsh Posté le 02-02-2006 à 15:55:33    

histoire de mieux saisir ce qu'il y a la dedans,
MSK : (aïe) 664057 lignes (645915 pour codsoc = 2) et (28776 lignes pour codsoc = 2 et datmvt between '20051231' and '20060131')
mais
codsoc = 2 et datmvt between '20051231' and '20060131' et codosk = 'INICPT' ca représente combien de lignes?

Reply

Marsh Posté le 02-02-2006 à 15:58:47    

Arjuna a écrit :

orafrance > ton truc ne marche que si on faut un rownum = 1 dans la requête, sinon il me ramène plein de lignes que je ne veux pas.


 
Un HAVING col2 = MAX(col2) devrait suffir non... sinon, je te dis qu'avec le fenêtrage ça va le faire -> fonctions analytiques :)

Reply

Marsh Posté le 02-02-2006 à 16:04:20    

casimimir a écrit :

histoire de mieux saisir ce qu'il y a la dedans,
MSK : (aïe) 664057 lignes (645915 pour codsoc = 2) et (28776 lignes pour codsoc = 2 et datmvt between '20051231' and '20060131')
mais
codsoc = 2 et datmvt between '20051231' and '20060131' et codosk = 'INICPT' ca représente combien de lignes?


1 ligne :sol:
 
en fait, pour le moment, il doit y avoir 1 ou deux lignes avec ce codosk dans toute la base, avant ils faisaient pas d'inventaire :sol:
 
mais dans un futur très proche, ils vont faire des inventaires souvent (inventaires rotatifs) et du coup je serai pas à l'abris d'avoir le même produit inventorié plusieurs fois dans une période assez courte.

Reply

Marsh Posté le 02-02-2006 à 16:05:59    

orafrance a écrit :

Un HAVING col2 = MAX(col2) devrait suffir non... sinon, je te dis qu'avec le fenêtrage ça va le faire -> fonctions analytiques :)


de mémoire, le having ne marche pas ni dans une sous-requête ni dans un union :spamafote:
 
pis tes requêtes analytiques, je panne rien (je comprends les exemple, mais je vois pas comment ils pourraient m'aider dans mon cas. par contre je garde sous le coude, parceque ça va bien me simplifier la vie pour d'autres requêtes. mais là je vois pas)

Reply

Marsh Posté le 02-02-2006 à 16:10:09    

donc dans le cas présent tu crées l'index qui va bien avec codsoc,datmvt,codosk et ta sousous-requete devrait aller déja mieux.
 
sinon c'est vrai que les fonctions analytiques ca a l'air costaud, je découvre ca aussi, et a mon avis on doit etre sur la meme page, http://lalystar.developpez.com/fonctionsAnalytiques/ , clair que je garde ca aussi sous le coude, mais la je suis en train de potasser le pl/sql, alors chaque chose en son temps lilalaa

Reply

Marsh Posté le 02-02-2006 à 16:12:15    

Pour info, ton explain plan avec tes 2 sous-requêtes imbriquées est le suivant :
 
SELECT STATEMENT Hint=RULE                                
  FILTER                                  
    TABLE ACCESS BY INDEX ROWID MSK                              
      NESTED LOOPS                                
        TABLE ACCESS BY INDEX ROWID PRO          
          INDEX RANGE SCAN WI_PRO                              
        INDEX RANGE SCAN MSK_IDX1                
    SORT AGGREGATE                                
      FILTER                                  
        INDEX RANGE SCAN MSK_IDX1                
        SORT AGGREGATE                                
          TABLE ACCESS BY INDEX ROWID MSK          
            INDEX RANGE SCAN MSK_WI_IDX2
 
edit : la requête que j'avais écrite au-dessus comprenait quelques erreurs (GROUP BY manquant par exemple), voic la version corrigée (mais sans données c'est pas évident de voir ce qui cloche) :
 

Code :
  1. SELECT * FROM (
  2. SELECT '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  3. FROM msk, pro,
  4.      (SELECT codsoc, codpro, sigdep, MAX(m2.nummsk) AS max_nummsk
  5.       FROM msk m2
  6.       WHERE m2.datmvt BETWEEN '20051231' AND '20060131'
  7.       AND m2.codosk = 'INICPT'
  8.       GROUP BY codsoc, codpro, sigdep) sub
  9. WHERE pro.codsoc = 2
  10. AND pro.sigfou = 'HERITAGE'
  11. AND msk.codsoc = pro.codsoc
  12. AND msk.codpro = pro.codpro
  13. AND msk.sigdep = pro.sigdep
  14. AND msk.numlot = ' '
  15. AND sub.codsoc = msk.codsoc
  16. AND sub.codpro = msk.codpro
  17. AND sub.sigdep = msk.sigdep
  18. AND msk.nummsk < sub.max_nummsk
  19. ORDER BY msk.nummsk DESC)
  20. WHERE ROWNUM = 1;


Message édité par Beegee le 02-02-2006 à 16:15:55
Reply

Marsh Posté le 02-02-2006 à 16:15:30    

c'est peut-être con... mais c'est vraiment utile le m1.nummsk < (select max(m2.nummsk) ?
 
Parce que j'vois mal comment nummsk ne pourrait pas être inférieur au max :/
 
Tu peux expliquer en français ce que fait la 1° requête STP ?
 
Les fonctions analytiques permettent d'appliquer une fonction de regroupement sur les lignes ramenées. Donc tu peux sélectionner le max d'une colonne dans un regroupement défini dans la fonction ce qui peut être très utile puisque GROUP BY doit lister toutes les colonnes.

Reply

Marsh Posté le 02-02-2006 à 16:17:24    

Apparemment il faut récupérer l'info des lignes ayant num_msk qui est l'avant-dernier d'après ce que j'ai compris ...
 
Est-ce que les num_msk sont incrémentés de 1 ? ou est-ce que c'est plus complexe ?

Reply

Marsh Posté le 02-02-2006 à 16:22:53    

Beegee a écrit :

Apparemment il faut récupérer l'info des lignes ayant num_msk qui est l'avant-dernier d'après ce que j'ai compris ...
 
Est-ce que les num_msk sont incrémentés de 1 ? ou est-ce que c'est plus complexe ?


"il sont censés", mais je n'en ai aucune garantie (l'ERP peut être configuré pour avoir un compteur gobale toutes oppérations/prouits/dépots/etc confondu, un ou compteur différent par dépot, par produit pour par les deux à la fois, etc. je ne peux donc pas faire de plans sur la comète à ce sujet. la seule chose que je sais, c'est que si un trou est créé, on ne le bouchera jamais (pas de bouclage du compteur)
 
d'ailleurs en regardant, contrairement à ce qui est indiqué dans l'index unique, j'ai un compteur par société et c'est tout (donc je dois pouvoir faire une clé unique sur (codsoc, nummvt), donc pour un même produit, les valeurs ne sont pas incrémentées de 1 en 1


Message édité par Arjuna le 02-02-2006 à 16:24:22
Reply

Marsh Posté le 02-02-2006 à 16:27:50    

casimimir a écrit :

donc dans le cas présent tu crées l'index qui va bien avec codsoc,datmvt,codosk et ta sousous-requete devrait aller déja mieux.


vu les deux index que j'ai déjà créé, je suis pas sur qu'il change grand chose (déjà un sir datmvt et un sur codosk, mais pas les deux à la fois)
 
mais bon, j'ai lancé la création quand même...
 
t'ain le tablespace des index, il a dû se prendre 2 Go facile dans la journée là :o

Reply

Marsh Posté le 02-02-2006 à 16:29:22    

beegee > le souci de ta requête, c'est que le rownum me retourne 1 ligne par fournisseur. moi j'en veux 1 par produit du fournisseur
 
 
Pour orafrance qui me fait répéter :o :p
 
Là j'expliquais la première requête :
 

Arjuna a écrit :

En fait, j'arrive pas à réécrire à la sauce orafrance/begee.
 
En français, le bout de requête qui merde ça donne :
 
Je veux récupérer, pour chaque produit du fournisseur "heritage" dans la société 2 la quantité de stock physique lors du dernier mouvement de stock avant la réinitialisation du compteur par les valeurs de l'inventaire le plus récent dans la période du 31/12/2005 au 31/01/2006
 
déjà, rien que pour comprendre ce que je veux, ça laisse rêveur [:atari]  
 
pour chaque produit du fournisseur "heritage" dans la société 2
=> pro.codsoc = 2 and pro.sigfou = 'HERITAGE'
 
quantité de stock physique
=> msk.c01
 
lors du dernier mouvement de stock
=> max(m1.nummsk) where m1.nummsk < m2.nummsk*
 
la réinitialisation du compteur par les valeurs de l'inventaire le plus récent
=> max(nummsk) where codosk = 'INICPT' (c'est le "m2.nummsk" de la ligne ci-dessus)
 
dans la période du 31/12/2005 au 31/01/2006
=> datmvt between '20051231' and '20060131'
 
et du coup j'arrive pas à faire autrement que mes deux sous-requêtes imbriquées



Message édité par Arjuna le 02-02-2006 à 16:30:52
Reply

Marsh Posté le 02-02-2006 à 16:31:25    

Quand tu parles de la première partie à optimiser, c'est ce boût de requête ?  
 

Code :
  1. select '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  2. from msk, pro
  3. where pro.codsoc = 2
  4. and pro.sigfou = 'HERITAGE'
  5. and msk.codsoc = pro.codsoc
  6. and msk.codpro = pro.codpro
  7. and msk.sigdep = pro.sigdep
  8. and msk.numlot = ' '
  9. and msk.nummsk =
  10. (select max(m1.nummsk)
  11. from msk m1
  12. where m1.codsoc = msk.codsoc
  13. and m1.codpro = msk.codpro
  14. and m1.sigdep = msk.sigdep
  15. and m1.numlot = ' '
  16. and m1.nummsk < (
  17. select max(m2.nummsk)
  18. from msk m2
  19. where m2.codsoc = m1.codsoc
  20. and m2.codpro = m1.codpro
  21. and m2.sigdep = m1.sigdep
  22. and m2.datmvt between '20051231' and '20060131'
  23. and m2.codosk = 'INICPT'
  24. ))


 
J'essaye de piocher quelques idées ça et là mais le sujet est vraiment vaste :whistle:
Je ne pense pas avoir les connaissances pour aider mais j'aimerai bien m'initier à l'optimisation des coûts :). Si vous avez des liens à fournir, j'ai déjà consulté ça :
 
http://sqlpro.developpez.com/cours/optimiser/
http://sqlpro.developpez.com/cours/arborescence/


Message édité par jeoff le 02-02-2006 à 16:36:11
Reply

Marsh Posté le 02-02-2006 à 16:32:37    

Pour info, voici les CREATE TABLE et INDEX simplifiés pour ceux qui veulent jouer avec les requêtes, avec un tout petit peu de données créées à la mano et les EXPLAIN PLAN correspondants :
 

Code :
  1. DROP TABLE msk;
  2. DROP TABLE pro;
  3. DROP TABLE osk;
  4. CREATE TABLE PRO
  5. (
  6.   CODPRO      VARCHAR2(16),
  7.   MOTCLE      VARCHAR2(16),
  8.   FAMPRO      VARCHAR2(6),
  9.   SFAPRO      VARCHAR2(6),
  10.   SSFPRO      VARCHAR2(6),
  11.   NOMPRO      VARCHAR2(30),
  12.   GENCOD      VARCHAR2(13),
  13.   CODDOU      VARCHAR2(16),
  14.   TYPPRO      VARCHAR2(3),
  15.   EXICOT      VARCHAR2(1),
  16.   CODTVA      VARCHAR2(1),
  17.   CODUNI      VARCHAR2(3),
  18.   QTEMIN      NUMBER,
  19.   CODTAX      VARCHAR2(1),
  20.   CODTAX2     VARCHAR2(1),
  21.   SIGDEP      VARCHAR2(12),
  22.   CODREA      VARCHAR2(6),
  23.   SUISTK      VARCHAR2(1),
  24.   PROSTK      VARCHAR2(16),
  25.   DELPRE      INTEGER,
  26.   SUISTT      VARCHAR2(1),
  27.   CLAABC      VARCHAR2(1),
  28.   DATMAR      VARCHAR2(8),
  29.   POIDS       NUMBER,
  30.   HAUTE       NUMBER,
  31.   LARGE       NUMBER,
  32.   LONGUE      NUMBER,
  33.   VOLUME      NUMBER,
  34.   CODTAR      VARCHAR2(16),
  35.   DESIGN1     VARCHAR2(40),
  36.   DESIGN2     VARCHAR2(40),
  37.   DESIGN3     VARCHAR2(40),
  38.   TYPTAR      VARCHAR2(3),
  39.   SIGFOU      VARCHAR2(12),
  40.   DATMOD      VARCHAR2(8),
  41.   UTIMOD      VARCHAR2(8),
  42.   REFPRO      VARCHAR2(16),
  43.   NUMVAR      INTEGER,
  44.   TPSMON      INTEGER,
  45.   INDCOM      VARCHAR2(1),
  46.   VA          VARCHAR2(2),
  47.   VL          VARCHAR2(2),
  48.   CODUVC      VARCHAR2(3),
  49.   CODUE       VARCHAR2(3),
  50.   NBUCUE      INTEGER,
  51.   PCB         INTEGER,
  52.   UNIPCB      VARCHAR2(3),
  53.   SPCB        INTEGER,
  54.   UNISPCB     VARCHAR2(3),
  55.   CODZN1      VARCHAR2(12),
  56.   CODZN2      VARCHAR2(12),
  57.   CODZN3      VARCHAR2(12),
  58.   CODZN4      VARCHAR2(12),
  59.   CODZN5      VARCHAR2(12),
  60.   CODZN6      VARCHAR2(12),
  61.   CODZN7      VARCHAR2(12),
  62.   CODZN8      VARCHAR2(12),
  63.   CODZN9      VARCHAR2(12),
  64.   CODZN10     VARCHAR2(12),
  65.   CODZN11     VARCHAR2(12),
  66.   CODZN12     VARCHAR2(12),
  67.   CODZN13     VARCHAR2(12),
  68.   CODZN14     VARCHAR2(12),
  69.   CODZN15     VARCHAR2(12),
  70.   CODZN16     VARCHAR2(12),
  71.   UNICOL      VARCHAR2(3),
  72.   COLEC1      VARCHAR2(1),
  73.   STCK1       INTEGER,
  74.   COLEC2      VARCHAR2(1),
  75.   STCK2       INTEGER,
  76.   COLEC3      VARCHAR2(1),
  77.   STCK3       INTEGER,
  78.   COLEC4      VARCHAR2(1),
  79.   STCK4       INTEGER,
  80.   COLEC5      VARCHAR2(1),
  81.   STCK5       INTEGER,
  82.   COLEC6      VARCHAR2(1),
  83.   STCK6       INTEGER,
  84.   COLEC7      VARCHAR2(1),
  85.   STCK7       INTEGER,
  86.   COLEC8      VARCHAR2(1),
  87.   STCK8       INTEGER,
  88.   COLEC9      VARCHAR2(1),
  89.   STCK9       INTEGER,
  90.   DESIGN4     VARCHAR2(40),
  91.   DESIGN5     VARCHAR2(40),
  92.   DESIGN6     VARCHAR2(40),
  93.   DESIGN7     VARCHAR2(40),
  94.   DESIGN8     VARCHAR2(40),
  95.   DESIGN9     VARCHAR2(40),
  96.   DESIGN10    VARCHAR2(40),
  97.   DESIGN11    VARCHAR2(40),
  98.   DESIGN12    VARCHAR2(40),
  99.   CODDEV      VARCHAR2(3),
  100.   CODBLOCAGE  VARCHAR2(3),
  101.   POIDSNET    NUMBER,
  102.   TYPAFF      VARCHAR2(6),
  103.   QOTITE      NUMBER,
  104.   UNISTA      VARCHAR2(3),
  105.   PROSTA      VARCHAR2(16),
  106.   INDCTS      VARCHAR2(1),
  107.   INDRIS      VARCHAR2(1),
  108.   VALPVR      NUMBER,
  109.   PDSPVR      NUMBER,
  110.   VOLPVR      NUMBER,
  111.   NUMLSK      INTEGER,
  112.   CODSOC      INTEGER,
  113.   DELREA      INTEGER,
  114.   DATCRE      VARCHAR2(8),
  115.   ETBCOD      VARCHAR2(3),
  116.   ETSSTATUT   VARCHAR2(1),
  117.   CODCONV     VARCHAR2(3),
  118.   CLAABCP     VARCHAR2(1),
  119.   DELPER      INTEGER,
  120.   SUIINS      VARCHAR2(1),
  121.   SUIICE      VARCHAR2(1),
  122.   NOMISE      VARCHAR2(1),
  123.   UNIICE      VARCHAR2(3),
  124.   TYPIFA      VARCHAR2(1),
  125.   UNIPER      VARCHAR2(3),
  126.   DELGAR      INTEGER,
  127.   UNIGAR      VARCHAR2(3),
  128.   ACHICE      VARCHAR2(1),
  129.   TYPICE      VARCHAR2(3),
  130.   SIGICE      VARCHAR2(12),
  131.   VERICE      INTEGER,
  132.   PRORUB      VARCHAR2(16),
  133.   TEECOD      VARCHAR2(1),
  134.   TEEUNI      VARCHAR2(3),
  135.   TEEPRX      NUMBER,
  136.   MODLOT      VARCHAR2(1),
  137.   CODPAY      VARCHAR2(3),
  138.   TTAICE      VARCHAR2(3),
  139.   CODMDL      VARCHAR2(6),
  140.   PROREF      VARCHAR2(16),
  141.   SUIREF      VARCHAR2(1),
  142.   REPART      NUMBER,
  143.   CODUNIC     VARCHAR2(60),
  144.   TYPREF      VARCHAR2(6),
  145.   DATFINMAR   VARCHAR2(8)
  146. );
  147. CREATE UNIQUE INDEX PRO_IDX1 ON PRO
  148. (CODSOC, CODPRO);
  149. CREATE INDEX PRO_IDX9 ON PRO
  150. (CODSOC, GENCOD);
  151. CREATE INDEX PRO_WEB_IX1 ON PRO
  152. (CODSOC, SIGFOU, FAMPRO, SSFPRO, SUISTK, CODBLOCAGE);
  153. CREATE INDEX WI_PRO ON PRO
  154. (CODSOC, SIGFOU);
  155. CREATE INDEX WI_PROZN15 ON PRO
  156. (CODSOC, CODZN15);
  157. CREATE TABLE MSK
  158. (
  159.   SIGDEP  VARCHAR2(12),
  160.   CODPRO  VARCHAR2(16),
  161.   NUMLOT  VARCHAR2(7),
  162.   NUMMSK  INTEGER,
  163.   NUMPER  INTEGER,
  164.   DATMVT  VARCHAR2(8),
  165.   HEUMVT  NUMBER,
  166.   DATPRV  VARCHAR2(8),
  167.   CODOSK  VARCHAR2(6),
  168.   CODEMP  VARCHAR2(10),
  169.   ACHVTE  VARCHAR2(1),
  170.   TYPEVE  VARCHAR2(3),
  171.   NUMEVE  INTEGER,
  172.   POSEVE  INTEGER,
  173.   LIGEVE  INTEGER,
  174.   QTEOPE  NUMBER,
  175.   QTEMVT  NUMBER,
  176.   PRXVTE  NUMBER,
  177.   DPA     NUMBER,
  178.   PUMP    NUMBER,
  179.   DECOTE  NUMBER,
  180.   C01     NUMBER,
  181.   C02     NUMBER,
  182.   C03     NUMBER,
  183.   C04     NUMBER,
  184.   C05     NUMBER,
  185.   C06     NUMBER,
  186.   C07     NUMBER,
  187.   C08     NUMBER,
  188.   C09     NUMBER,
  189.   C10     NUMBER,
  190.   C11     NUMBER,
  191.   C12     NUMBER,
  192.   C13     NUMBER,
  193.   C14     NUMBER,
  194.   CODUNI  VARCHAR2(3),
  195.   UNIFAC  VARCHAR2(3),
  196.   DATMOD  VARCHAR2(8),
  197.   UTIMOD  VARCHAR2(8),
  198.   TYPOSK  VARCHAR2(3),
  199.   NUMDEB  VARCHAR2(12),
  200.   NUMFIN  VARCHAR2(12),
  201.   PRXREV  NUMBER,
  202.   CODSOC  INTEGER,
  203.   NUMOF   VARCHAR2(10),
  204.   LIBMSK  VARCHAR2(30),
  205.   INDTRT  VARCHAR2(1),
  206.   INDCES  VARCHAR2(1),
  207.   CODFCT  VARCHAR2(8),
  208.   CODPEV  VARCHAR2(8)
  209. );
  210. CREATE UNIQUE INDEX MSK_IDX1 ON MSK
  211. (CODSOC, CODPRO, SIGDEP, NUMLOT, NUMMSK);
  212. CREATE INDEX MSK_WI_IDX1 ON MSK
  213. (CODSOC, CODPRO, SIGDEP, DATMVT);
  214. CREATE INDEX MSK_WI_IDX2 ON MSK
  215. (CODSOC, CODPRO, SIGDEP, CODOSK);
  216. CREATE TABLE OSK
  217. (
  218.   CODOSK     VARCHAR2(6),
  219.   LIBOSK     VARCHAR2(30),
  220.   LIROSK     VARCHAR2(10),
  221.   OPEC01     VARCHAR2(1),
  222.   OPEC02     VARCHAR2(1),
  223.   OPEC03     VARCHAR2(1),
  224.   OPEC04     VARCHAR2(1),
  225.   OPEC05     VARCHAR2(1),
  226.   OPEC06     VARCHAR2(1),
  227.   OPEC07     VARCHAR2(1),
  228.   OPEC08     VARCHAR2(1),
  229.   OPEC09     VARCHAR2(1),
  230.   OPEC10     VARCHAR2(1),
  231.   OPEC11     VARCHAR2(1),
  232.   OPEC12     VARCHAR2(1),
  233.   OPEC13     VARCHAR2(1),
  234.   OPEC14     VARCHAR2(1),
  235.   PRVC01     VARCHAR2(1),
  236.   PRVC02     VARCHAR2(1),
  237.   PRVC03     VARCHAR2(1),
  238.   PRVC04     VARCHAR2(1),
  239.   PRVC05     VARCHAR2(1),
  240.   PRVC06     VARCHAR2(1),
  241.   PRVC07     VARCHAR2(1),
  242.   PRVC08     VARCHAR2(1),
  243.   PRVC09     VARCHAR2(1),
  244.   PRVC10     VARCHAR2(1),
  245.   PRVC11     VARCHAR2(1),
  246.   PRVC12     VARCHAR2(1),
  247.   PRVC13     VARCHAR2(1),
  248.   PRVC14     VARCHAR2(1),
  249.   LOTOBL     VARCHAR2(1),
  250.   CALPMP     VARCHAR2(1),
  251.   OPEMAN     VARCHAR2(1),
  252.   TYPEVE     VARCHAR2(3),
  253.   CSKTE1     VARCHAR2(6),
  254.   OPETST     VARCHAR2(2),
  255.   CSKTE2     VARCHAR2(6),
  256.   OPEQT1     VARCHAR2(1),
  257.   CSKQT1     VARCHAR2(6),
  258.   OPEQT2     VARCHAR2(1),
  259.   CSKQT2     VARCHAR2(6),
  260.   OPEQT3     VARCHAR2(1),
  261.   CSKQT3     VARCHAR2(6),
  262.   CSKSUI     VARCHAR2(6),
  263.   OPESU1     VARCHAR2(1),
  264.   CSKSU1     VARCHAR2(6),
  265.   OPESU2     VARCHAR2(1),
  266.   CSKSU2     VARCHAR2(6),
  267.   OPESU3     VARCHAR2(1),
  268.   CSKSU3     VARCHAR2(6),
  269.   TYPOSK     VARCHAR2(3),
  270.   DATMOD     VARCHAR2(8),
  271.   UTIMOD     VARCHAR2(8),
  272.   TYPCTR     VARCHAR2(1),
  273.   EMPLOBL    VARCHAR2(1),
  274.   MAJINV     VARCHAR2(1),
  275.   GENMSK     VARCHAR2(1),
  276.   SEROBL     VARCHAR2(1),
  277.   CODSOC     INTEGER,
  278.   CODCSK     VARCHAR2(6),
  279.   OPECSK     VARCHAR2(1),
  280.   CODUT_MES  VARCHAR2(10),
  281.   PROPRIETE  VARCHAR2(1)
  282. );
  283. CREATE UNIQUE INDEX OSK_IDX1 ON OSK
  284. (CODSOC, CODOSK);
  285. INSERT INTO msk
  286. (codsoc, codpro, sigdep, c01, numlot, nummsk, datmvt, codosk)
  287. VALUES
  288. (2, 1, 1, 1, ' ', 1, '20060101', 'INICPT');
  289. INSERT INTO msk
  290. (codsoc, codpro, sigdep, c01, numlot, nummsk, datmvt, codosk)
  291. VALUES
  292. (2, 1, 1, 1, ' ', 2, '20060101', 'INICPT');
  293. INSERT INTO msk
  294. (codsoc, codpro, sigdep, c01, numlot, nummsk, datmvt, codosk)
  295. VALUES
  296. (2, 1, 1, 1, ' ', 3, '20060101', 'INICPT');
  297. INSERT INTO pro
  298. (codsoc, codpro, sigfou, sigdep, codblocage)
  299. VALUES
  300. (2, 1, 'HERITAGE', 1, 1);
  301. SELECT '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  302. FROM msk, pro
  303. WHERE pro.codsoc = 2
  304. AND pro.sigfou = 'HERITAGE'
  305. AND msk.codsoc = pro.codsoc
  306. AND msk.codpro = pro.codpro
  307. AND msk.sigdep = pro.sigdep
  308. AND msk.numlot = ' '
  309. AND msk.nummsk = 
  310. (SELECT MAX(m1.nummsk)
  311. FROM msk m1
  312. WHERE m1.codsoc = msk.codsoc
  313. AND m1.codpro = msk.codpro
  314. AND m1.sigdep = msk.sigdep
  315. AND m1.numlot = ' '
  316. AND m1.nummsk < (
  317. SELECT MAX(m2.nummsk)
  318. FROM msk m2
  319. WHERE m2.codsoc = m1.codsoc
  320. AND m2.codpro = m1.codpro
  321. AND m2.sigdep = m1.sigdep
  322. AND m2.datmvt BETWEEN '20051231' AND '20060131'
  323. AND m2.codosk = 'INICPT'
  324. ));
  325. EXPLAIN PLAN :
  326. SELECT STATEMENT Hint=RULE                             
  327.   FILTER                             
  328.     TABLE ACCESS BY INDEX ROWID MSK                            
  329.       NESTED LOOPS                             
  330.         TABLE ACCESS BY INDEX ROWID PRO                            
  331.           INDEX RANGE SCAN WI_PRO                            
  332.         INDEX RANGE SCAN MSK_IDX1                            
  333.     SORT AGGREGATE                             
  334.       FILTER                             
  335.         INDEX RANGE SCAN MSK_IDX1                            
  336.         SORT AGGREGATE                             
  337.           TABLE ACCESS BY INDEX ROWID MSK                            
  338.             INDEX RANGE SCAN MSK_WI_IDX2                            
  339. SELECT * FROM (
  340. SELECT '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  341. FROM msk, pro,
  342.      (SELECT codsoc, codpro, sigdep, MAX(m2.nummsk) AS max_nummsk
  343.       FROM msk m2
  344.       WHERE m2.datmvt BETWEEN '20051231' AND '20060131'
  345.       AND m2.codosk = 'INICPT'
  346.       GROUP BY codsoc, codpro, sigdep) sub
  347. WHERE pro.codsoc = 2
  348. AND pro.sigfou = 'HERITAGE'
  349. AND msk.codsoc = pro.codsoc
  350. AND msk.codpro = pro.codpro
  351. AND msk.sigdep = pro.sigdep
  352. AND msk.numlot = ' '
  353. AND sub.codsoc = msk.codsoc
  354. AND sub.codpro = msk.codpro
  355. AND sub.sigdep = msk.sigdep
  356. AND msk.nummsk < sub.max_nummsk
  357. ORDER BY msk.nummsk DESC)
  358. WHERE ROWNUM = 1;
  359. EXPLAIN PLAN :
  360. SELECT STATEMENT Hint=RULE                             
  361.   COUNT STOPKEY                             
  362.     VIEW                             
  363.       FILTER                             
  364.         SORT GROUP BY                             
  365.           TABLE ACCESS BY INDEX ROWID MSK                            
  366.             NESTED LOOPS                             
  367.               NESTED LOOPS                             
  368.                 TABLE ACCESS BY INDEX ROWID PRO                            
  369.                   INDEX RANGE SCAN WI_PRO                            
  370.                 TABLE ACCESS BY INDEX ROWID MSK                            
  371.                   INDEX RANGE SCAN MSK_IDX1                            
  372.               INDEX RANGE SCAN MSK_WI_IDX2


 
Arjuna : pourrais-tu lancer la dernière requête et me dire ce qui cloche ? (si les données retournées ne sont pas les mêmes tu devrais arriver à voir ce qui cloche ...)

Reply

Marsh Posté le 02-02-2006 à 16:35:30    

mmm pour les explain plan faut quand meme préciser que c'est sur une table non peuplée

Reply

Marsh Posté le 02-02-2006 à 16:35:51    

Oui, c'est ce morceau (il a légèrement changé depuis ce matin, mais toujours grossomodo le même)
 

Code :
  1. select pro.sigfou, pro.sigdep, pro.codpro, pro.codblocage, pro.datmar, pro.nompro, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv, 0 variationinv
  2. from msk, pro
  3. where pro.codsoc = 2
  4. and pro.sigfou = 'HERITAGE'
  5. and msk.codsoc = pro.codsoc
  6. and msk.codpro = pro.codpro
  7. and msk.sigdep = pro.sigdep
  8. and msk.numlot = ' '
  9. and msk.nummsk =
  10. (
  11.   select max(m1.nummsk)
  12.  from msk m1
  13.  where m1.codsoc = msk.codsoc
  14.  and m1.codpro = msk.codpro
  15.  and m1.sigdep = msk.sigdep
  16.  and m1.numlot = ' '
  17.  and m1.nummsk <
  18.  (
  19.   select max(m2.nummsk)
  20.   from msk m2
  21.   where m2.codsoc = m1.codsoc
  22.   and m2.codpro = m1.codpro
  23.   and m2.sigdep = m1.sigdep
  24.   and m2.datmvt between '20051231' and '20060131'
  25.   and m2.codosk = 'INICPT'
  26.  )
  27. )


 
(avec la requête totale et complètée -j'en ai rajouté encore un peu part rapport à ce matin-)
 

Code :
  1. select sigfou, sigdep, codpro, codblocage, datmar, nompro, sum(entrees) entress, sum(sorties) sorties, sum(initinventaire) initinventaire, sum(avantinv) avantint, sum(variationinv) variationinv
  2. from
  3. (
  4. select pro.sigfou, pro.sigdep, pro.codpro, pro.codblocage, pro.datmar, pro.nompro, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv, 0 variationinv
  5. from msk, pro
  6. where pro.codsoc = 2
  7. and pro.sigfou = 'HERITAGE'
  8. and msk.codsoc = pro.codsoc
  9. and msk.codpro = pro.codpro
  10. and msk.sigdep = pro.sigdep
  11. and msk.numlot = ' '
  12. and msk.nummsk =
  13. (
  14.   select max(m1.nummsk)
  15.  from msk m1
  16.  where m1.codsoc = msk.codsoc
  17.  and m1.codpro = msk.codpro
  18.  and m1.sigdep = msk.sigdep
  19.  and m1.numlot = ' '
  20.  and m1.nummsk <
  21.  (
  22.   select max(m2.nummsk)
  23.   from msk m2
  24.   where m2.codsoc = m1.codsoc
  25.   and m2.codpro = m1.codpro
  26.   and m2.sigdep = m1.sigdep
  27.   and m2.datmvt between '20051231' and '20060131'
  28.   and m2.codosk = 'INICPT'
  29.  )
  30. )
  31. union all
  32. select pro.sigfou, pro.sigdep, pro.codpro, pro.codblocage, pro.datmar, pro.nompro, 0 entreesapres, 0 sortiesapres, msk.c01 initinventaire, 0 avantinv, 0 variationinv
  33. from msk, pro
  34. where pro.codsoc = 2
  35. and pro.sigfou = 'HERITAGE'
  36. and msk.codsoc = pro.codsoc
  37. and msk.sigdep = pro.sigdep
  38. and msk.codpro = pro.codpro
  39. and msk.datmvt between '20051231' and '20060131'
  40. and msk.codosk = 'INICPT'
  41. and msk.c01 != 0
  42. union all
  43. select pro.sigfou, pro.sigdep, pro.codpro, pro.codblocage, pro.datmar, pro.nompro, sum(msk.qteope * decode(osk.opec01, '+', 1, 0)) entreesapres, sum(msk.qteope * decode(osk.opec01, '-', 1, 0)) sortiesapres, 0 initinventaire, 0 avantinv, 0 variationinv
  44. from osk, msk, pro
  45. where pro.codsoc = 2
  46. and pro.sigfou = 'HERITAGE'
  47. and msk.codsoc = pro.codsoc
  48. and msk.sigdep = pro.sigdep
  49. and msk.codpro = pro.codpro
  50. and msk.datmvt between '20051231' and '20060131'
  51. and osk.codsoc = msk.codsoc
  52. and osk.codosk = msk.codosk
  53. and osk.opec01 != ' '
  54. and
  55. (
  56.   msk.nummsk > (select max(nummsk) from msk m where m.codsoc = msk.codsoc and m.sigdep = msk.sigdep and m.codpro = msk.codpro and m.datmvt between '20051231' and '20060131' and m.codosk in ('INICPT', 'INVV'))
  57.   or
  58.   not exists (select null from msk m where m.codsoc = msk.codsoc and m.sigdep = msk.sigdep and m.codpro = msk.codpro and m.datmvt between '20051231' and '20060131' and m.codosk in ('INICPT', 'INVV'))
  59. )
  60. group by pro.sigfou, pro.codpro, pro.codblocage, pro.datmar, pro.nompro, pro.sigdep
  61. union all
  62. select pro.sigfou, pro.sigdep, pro.codpro, pro.codblocage, pro.datmar, pro.nompro, 0 entreesapres, 0 sortiesapres, 0 initinventaire, 0 avantinv, sum(msk.qteope) variationinv
  63. from msk, pro
  64. where pro.codsoc = 2
  65. and pro.sigfou = 'HERITAGE'
  66. and msk.codsoc = pro.codsoc
  67. and msk.sigdep = pro.sigdep
  68. and msk.codpro = pro.codpro
  69. and msk.datmvt between '20051231' and '20060131'
  70. and msk.codosk = 'INVV'
  71. and
  72. (
  73.   msk.nummsk > (select max(nummsk) from msk m where m.codsoc = msk.codsoc and m.sigdep = msk.sigdep and m.codpro = msk.codpro and m.datmvt between '20051231' and '20060131' and m.codosk = 'INICPT')
  74.   or
  75.   not exists (select null from msk m where m.codsoc = msk.codsoc and m.sigdep = msk.sigdep and m.codpro = msk.codpro and m.datmvt between '20051231' and '20060131' and m.codosk = 'INICPT')
  76. )
  77. group by pro.sigfou, pro.codpro, pro.codblocage, pro.sigdep, pro.datmar, pro.nompro
  78. )
  79. group by sigfou, sigdep, codpro, codblocage, datmar, nompro


 
PS: Je viens de shooter le nouvel index, comme je pensais, ça change rien à la durée de la requête (la période porte sur trop peux de lignes pour que ce soit intéressant de filtrer par codosk)

Reply

Marsh Posté le 02-02-2006 à 16:39:38    

c'est ça qui cloche : "1 ligne(s) séléctionnée(s)" en 1 minutes 29 secondes
 
moi j'en ai 124 lignes en 12 secondes :/

Reply

Marsh Posté le 02-02-2006 à 16:40:39    

(en fait, ton petit bout de requête tout seul met plus de temps à tourner que ma requête toute entière :D)
 
ceci dit, je te remercie de passer du temps à m'aider à chercher une solution :)
 
bon, je vais aller fumer un café dehors, ça va me rafraîchier l'esprit, chuis en train de choper mal à la tête)


Message édité par Arjuna le 02-02-2006 à 16:41:36
Reply

Marsh Posté le 02-02-2006 à 16:46:04    

Ouaip j'ai vu , j'ai posté en //.
 
Pas évident à 1ère vue de modifier la requête ...

Reply

Marsh Posté le 02-02-2006 à 16:54:02    

erf, j'ai foutu le serveur à genoux y'a tout le monde qui râle dans les couloirs :D


Message édité par Arjuna le 02-02-2006 à 16:54:38
Reply

Marsh Posté le 02-02-2006 à 16:54:36    

Tu as essayé un index sur codsoc, codpro, sigdep ?
 
Voici ce que ça donne sur ta requête, ainsi que sur la requête réécrite avec 2 GROUP BY :
 

Code :
  1. CREATE INDEX msk_myindex ON msk
  2. (codsoc, codpro, sigdep);
  3. SELECT '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  4. FROM msk, pro
  5. WHERE pro.codsoc = 2
  6. AND pro.sigfou = 'HERITAGE'
  7. AND msk.codsoc = pro.codsoc
  8. AND msk.codpro = pro.codpro
  9. AND msk.sigdep = pro.sigdep
  10. AND msk.numlot = ' '
  11. AND msk.nummsk = 
  12. (SELECT MAX(m1.nummsk)
  13. FROM msk m1
  14. WHERE m1.codsoc = msk.codsoc
  15. AND m1.codpro = msk.codpro
  16. AND m1.sigdep = msk.sigdep
  17. AND m1.numlot = ' '
  18. AND m1.nummsk < (
  19. SELECT MAX(m2.nummsk)
  20. FROM msk m2
  21. WHERE m2.codsoc = m1.codsoc
  22. AND m2.codpro = m1.codpro
  23. AND m2.sigdep = m1.sigdep
  24. AND m2.datmvt BETWEEN '20051231' AND '20060131'
  25. AND m2.codosk = 'INICPT'
  26. ));
  27. --EXPLAIN PLAN :
  28. --SELECT STATEMENT Hint=RULE                             
  29. --  FILTER                             
  30. --    TABLE ACCESS BY INDEX ROWID MSK                            
  31. --      NESTED LOOPS                             
  32. --        TABLE ACCESS BY INDEX ROWID PRO                            
  33. --          INDEX RANGE SCAN WI_PRO                            
  34. --        INDEX RANGE SCAN MSK_MYINDEX                            
  35. --    SORT AGGREGATE                             
  36. --      FILTER                             
  37. --        TABLE ACCESS BY INDEX ROWID MSK                            
  38. --          INDEX RANGE SCAN MSK_MYINDEX                            
  39. --        SORT AGGREGATE                             
  40. --          TABLE ACCESS BY INDEX ROWID MSK                            
  41. --            INDEX RANGE SCAN MSK_WI_IDX2                            
  42. SELECT '1' ord, pro.sigfou, msk.sigdep, pro.codpro, pro.codblocage, 0 entrees, 0 sorties, 0 initinventaire, msk.c01 avantinv
  43. FROM msk, pro,
  44.      (SELECT m1.codsoc, m1.codpro, m1.sigdep, MAX(m1.nummsk) AS prev_nummsk
  45.       FROM msk m1,
  46.           (SELECT codsoc, codpro, sigdep, MAX(m2.nummsk) AS max_nummsk
  47.            FROM msk m2
  48.            WHERE m2.datmvt BETWEEN '20051231' AND '20060131'
  49.            AND m2.codosk = 'INICPT'
  50.            GROUP BY codsoc, codpro, sigdep) sub
  51.       WHERE sub.codsoc = m1.codsoc
  52.       AND sub.codpro = m1.codpro
  53.       AND sub.sigdep = m1.sigdep
  54.       AND m1.numlot = ' '
  55.       AND m1.nummsk < sub.max_nummsk
  56.       GROUP BY m1.codsoc, m1.codpro, m1.sigdep) sub2
  57. WHERE pro.codsoc = 2
  58. AND pro.sigfou = 'HERITAGE'
  59. AND msk.codsoc = pro.codsoc
  60. AND msk.codpro = pro.codpro
  61. AND msk.sigdep = pro.sigdep
  62. AND msk.numlot = ' '
  63. AND msk.codsoc = sub2.codsoc
  64. AND msk.codpro = sub2.codpro
  65. AND msk.sigdep = sub2.sigdep
  66. AND msk.nummsk = sub2.prev_nummsk;
  67. --EXPLAIN PLAN :
  68. --SELECT STATEMENT Hint=RULE                             
  69. --  FILTER                             
  70. --    SORT GROUP BY                             
  71. --      TABLE ACCESS BY INDEX ROWID MSK                            
  72. --        NESTED LOOPS                             
  73. --          NESTED LOOPS                             
  74. --            VIEW                             
  75. --              FILTER                             
  76. --                SORT GROUP BY                             
  77. --                  TABLE ACCESS BY INDEX ROWID MSK                            
  78. --                    NESTED LOOPS                             
  79. --                      INDEX RANGE SCAN MSK_IDX1                            
  80. --                      INDEX RANGE SCAN MSK_WI_IDX2                            
  81. --            TABLE ACCESS BY INDEX ROWID PRO                            
  82. --              INDEX RANGE SCAN WI_PRO                            
  83. --          INDEX RANGE SCAN MSK_MYINDEX

Message cité 1 fois
Message édité par Beegee le 02-02-2006 à 16:55:43
Reply

Marsh Posté le 02-02-2006 à 16:56:45    

Beegee a écrit :

Tu as essayé un index sur codsoc, codpro, sigdep ?


 
ben les 3 index de la table tapent contiennent déjà ce triplet en première position, donc "oui"
 
pis je crée plus d'index aujourd'hui, à chaque fois tout le monde est boqué 10 minutes... :D

Reply

Marsh Posté le 02-02-2006 à 17:04:44    

Bon, allez, je lance la requête pour tous les fournisseurs confondus... Après tout, avec beaucoup de chance, ce sera pas beaucoup plus lent :ange:
(l'espoir fait vivre :D)

Reply

Marsh Posté le 02-02-2006 à 17:06:02    

Une petite question bête : est-ce que vous savez pourquoi quand je lance une requête avec TOAD, ce dernier occupe 100% du CPU durant toute la requête :??:
 
Genre on dirait que c'est lui qui execute la requête !

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed