Oui un seul index sur (FLAG_JOURNAL, STATUS)
Oui un seul index sur (FLAG_JOURNAL, STATUS)
Heuuu, qlq explications ne seraient pas de trop...![]()
Votre flag est un caractere ???
oui :
Code : Sélectionner tout - Visualiser dans une fenêtre à part VARCHAR2(1)
J'ai simplifié ma requête :
Avec un index sur 'JOURNAL'.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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?![]()
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 : 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
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : 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
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 avec
Code : Sélectionner tout - Visualiser dans une fenêtre à part '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 : Sélectionner tout - Visualiser dans une fenêtre à part
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;![]()
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 ?
Partager