J'ai une requête commeoracle supprimer requête qui prend trop de temps
DELETE from tablename where colname = value;
qui prend terriblement longtemps pour exécuter. Quelle pourrait être la raison? J'ai un index sur colname.
J'ai une requête commeoracle supprimer requête qui prend trop de temps
DELETE from tablename where colname = value;
qui prend terriblement longtemps pour exécuter. Quelle pourrait être la raison? J'ai un index sur colname.
Il pourrait y avoir plusieurs explications pour expliquer pourquoi votre requête prend beaucoup de temps:
SELECT NULL FROM tablename WHERE colname=:value FOR UPDATE NOWAIT
,ON DELETE TRIGGER
qui fonctionne plus,UNINDEXED REFERENCE CONSTRAINTS
pointant vers cette table (il y a une script from AskTom qui aidera vous déterminez si de telles clés étrangères non indexées existent).merci pour la réponse, mais pas les options 1 et 2. – Ajay
3ème était en fait la solution :). Maintenant, il s'exécute dans les 2 secondes! – Ajay
heureux d'aider =). En fait, je devrais probablement avoir mis le troisième point dans la place numéro 1, car il est le plus susceptible d'être négligé –
Il se peut que votre table soit liée à plusieurs tables ayant un nombre de lignes énorme.
yup. correct! C'était une énorme table parent – Ajay
Quelle est la sélectivité de cet indice? Si votre table a un million de lignes et que cette valeur en touche cent cinquante mille, votre index est inutile. En fait, il peut être pire qu'inutile si elle est réellement utilisée. Rappelez-vous, un DELETE est comme une instruction SELECT: nous pouvons ajuster son chemin d'accès. De plus, les suppressions occupent beaucoup d'espace de table d'annulation, ce qui fait que vous risquez de souffrir de conflits si le système est très sollicité. Dans un système multi-utilisateur, une autre session peut avoir un verrou sur les lignes que vous souhaitez supprimer.
Avez-vous des déclencheurs ON DELETE? Avez-vous des contraintes de clé étrangère DELETE CASCADE? Étant donné tout ce que vous dites, et en particulier la colonne en question étant la clé primaire de sorte que vous essayez de supprimer une seule ligne, si cela prend beaucoup de temps, il est beaucoup plus probable que d'autres processus ou l'utilisateur a un verrou sur la ligne. Est-ce que quelque chose apparaît dans V$LOCK
?
Non Activé Supprimer les déclencheurs. La table a plus de 1 million de lignes. La colonne indexée est la clé primaire. Pas de contraintes SUPPRIMER CASCADE. J'ai encore une autre table parente avec> 1 million de lignes prenant juste une seconde pour supprimer une ligne! – Ajay
Votre table contient-elle plus d'enregistrements?
Existe-t-il des programmes récursifs (certaines boucles imbriquées, etc.) s'exécutant sur le serveur de base de données?
Vérifiez les problèmes réseau si le serveur de base de données se trouve sur des machines différentes?
Pas de pgms récursif côté serveur. Pas de problème nm – Ajay
Si quelque chose est lent, et vous ne savez pas pourquoi, tracez-le et découvrez.
How do I troubleshoot performance problems with an Oracle SQL statement
Je vais donc poster mon expérience. Ça pourrait être utile pour quelqu'un.
La requête
delete from foo
where foo_id not in (
select max(foo_id) from foo group by foo_bar_id, foo_qux_id
);
a pris 16 sec. la suppression de 1700 enregistrements de 2300 au total dans le tableau foo
.
J'ai vérifié tous les index sur les clés étrangères comme indiqué dans d'autres réponses. Cela n'a pas aidé.
Solution:
Changé la requête
delete from foo
where foo_id in (
select foo_id from foo
minus
select max(foo_id) from foo group by foo_bar_id, foo_qux_id
);
J'ai changé not in
-in
et utilisé minus
pour obtenir un résultat correct.
Maintenant, la requête s'exécute en 0,04 sec.
Pourriez-vous poster le plan d'explication de votre requête (dans SQL * Plus, exécutez "SET AUTOTRACE ON EXPLAIN" puis votre requête)? –
SQL> définir autotrace sur expliquer SQL> delete from nom_table où nid = 1250626; 1 ligne supprimée. Plan d'exécution ------------------------------------------------ ---------- 0 DELETE STATEMENT Optimizer = ALL_ROWS (Coût = 2 Card = 1 Bytes = 48) 1 0 SUPPRIMER 'tablename' 2 1 INDEX (UNIQUE SCAN) de 'PK_tablename' (INDEX (UNIQUE)) (Coût = 1 carte = 1 octet = 48) Ceci est pour la suppression de 1 ligne. La requête d'origine a une condition '> =', que je ne pouvais pas voir un achèvement jusqu'à environ 20 minutes. Même avec '=', cela prend plus d'une minute – Ajay
Qu'en est-il des performances de * SELECT * FROM nom_table WHERE nid = 1250626; *? – Christian13467