Oui un seul index sur (FLAG_JOURNAL, STATUS)
Version imprimable
Oui un seul index sur (FLAG_JOURNAL, STATUS)
Rhoooo le COST :aie:
Heuuu, qlq explications ne seraient pas de trop...:mouarf:
Votre flag est un caractere ???
oui :Code:VARCHAR2(1)
J'ai simplifié ma requête :
Avec un index sur 'JOURNAL'.Code:
1
2
3
4
5 update Table set JOURNAL = 'AUTRE' , FLAG_JOURNAL = w_CTRL_JOURNAL , FLAG_LIGNE = greatest (w_CTRL_JOURNAL, FLAG_LIGNE) where JOURNAL = 'AUTRE_0'
Mais cette requête me prend 4 min sur une table de 2,5 millions de lignes.
Est ce que c'est normal?:calim2:
C'est pas délirant, faut voir si il y a des indexes sur les colonnes mises à jour, ce qui imposerait de les mettre à jour et donc prend du temps, les perfs des disques, la fragmentation, etc.
Encore une fois, sans trace point de salut :?
bonjour,
voici des informations utiles :
La table fait : 2 551 724 enregistrements.
dont : 133 406 avec JOURNAL = 'AUTRE_0'
et : 2 418 318 avec JOURNAL = 'AUTRE'
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 SQL> create index INTERFACE_ND3 on INTERFACE(JOURNAL); Index créé. Ecoulé : 00 :00 :19.31 SQL> update INTERFACE set 2 JOURNAL = 'AUTRE' 3 , FLAG_JOURNAL ='2' 4 , FLAG_LIGNE = greatest('2' , FLAG_LIGNE ) 5 where JOURNAL = 'AUTRE_0'; 2418318 ligne(s) mise(s) à jour. Ecoulé : 00 :04 :08.39 Plan d'exécution ---------------------------------------------------------- 0 UPDATE STATEMENT Optimizer=ALL_ROWS (Cost=66760 Card=2533034 Bytes=27863374) 1 0 UPDATE OF 'INTERFACE' 2 1 TABLE ACCESS (FULL) OF 'INTERFACE' (TABLE) (Cost= 66760 Card=2533034 Bytes=27863374) Statistiques ---------------------------------------------------------- 33109 recursive calls 17624580 db block gets 577957 consistent gets 225215 physical reads 2071711192 redo size 389 bytes sent via SQL*Net to client 436 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 2 sorts (memory)
Salut !
Pas sûr que ça change quelque chose, mais réessaie après avoir calculé les statistiques sur ton index...
Code:
1
2 exec dbms_stats.gather_index_stats(null, 'INTERFACE_ND3')
c'est fait et j'ai lancé encore une fois la requête :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 SQL> update INTERFACE set 2 JOURNAL = 'AUTRE' 3 , FLAG_JOURNAL ='2' 4 , FLAG_LIGNE = greatest('2' , FLAG_LIGNE ) 5 where JOURNAL = 'AUTRE_0'; 2418318 ligne(s) mise(s) à jour. Ecoulé : 00 :03 :55.32 Plan d'exécution ---------------------------------------------------------- 0 UPDATE STATEMENT Optimizer=ALL_ROWS (Cost=66760 Card=2533034 Bytes=27863374) 1 0 UPDATE OF 'INTERFACE' 2 1 TABLE ACCESS (FULL) OF 'INTERFACE' (TABLE) (Cost= 66760 Card=2533034 Bytes=27863374) Statistiques ---------------------------------------------------------- 170 recursive calls 17124612 db block gets 240323 consistent gets 248659 physical reads 1839948160 redo size 392 bytes sent via SQL*Net to client 441 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 2418318 rows processed
Oui désolé c'est l'inverse.
Il y a beaucoup plus de ligne avecCode:'AUTRE_0'
Bah oui, il utilise pas l'index du coup, c'est normal :?
Tu dois faire cette opération souvent ?
Parce que 4 minutes en oneshot, c'est pas la mort...
... sinon tu peux te demander pour qu'elle raison tu dois faire ça... et revoir ta logique de traitement.
Et en dernier recours, tu as les méthodes brutales CTAS :
A manier avec prudence (et adaptation sur les contraintes indexes, ...), et en accord avec ton DBA :)Code:
1
2
3
4
5
6
7
8
9
10 CREATE TABLE INTERFACETMP AS SELECT Lescolonnespasmisesàjour, CASE WHEN JOURNAL = 'AUTRE_0' THEN 'AUTRE' ELSE JOURNAL END as journal, CASE WHEN JOURNAL = 'AUTRE_0' THEN '2' ELSE FLAG_JOURNAL END as flag_journal, CASE WHEN JOURNAL = 'AUTRE_0' THEN greatest('2', FLAG_LIGNE) ELSE FLAG_LIGNE END as flag_ligne FROM INTERFACE; DROP TABLE INTERFACE; ALTER TABLE INTERFACETMP RENAME TO INTERFACE;
J'ai pas pensé à prendre ma boule de crystal et comme tu sembles pas décidé à nous sortir les traces ça risque d'être compliqué de répondre :aie:
Mais je doute que tu puisses faire grand chose, il y a tout à croire que le temps passe dans les I/O, donc faut optimiser les accès disque.
Oui, supprimer vos index les colonnes de l'update : JOURNAL, FLAG_JOURNAL et FLAG_LIGNE.
Celui sur JOURNAL, vous l'avez créé pour ce besoin mais en fait vous ne l'utilisez pas, et vous le mettez à jour vraiment pour rien.
Si vous avez besoin pour d'autres requêtes des index, s'ils existent sur FLAG_JOURNAL et FLAG_LIGNE, il faut comparer le temps de mise à jour avec index et celui de mise à jour sans index + reconstruction.
Pas dit que la différence soit flagrante, et attention aux accès concurrents si vous supprimez l'index.
L'index sur la colone journal ne sert à rien.
Mais, je pense que votre table a un(des) trigger(s) en Update (probablement For each Row). Je me trompe ou pas ?