J'ai une question comme
DELETE from tablename where colname = value;
qui prend énormément de temps à exécuter ..__Quelle pourrait en être la raison? J'ai un index sur colname.
Plusieurs raisons peuvent expliquer pourquoi votre requête prend beaucoup de temps:
SELECT NULL FROM tablename WHERE colname=:value FOR UPDATE NOWAIT
,ON DELETE TRIGGER
qui fait du travail supplémentaire,UNINDEXED REFERENCE CONSTRAINTS
pointant vers cette table (il existe un script de AskTom qui vous aidera à déterminer si de telles clés étrangères non indexées existent).il se peut que votre table soit liée à plusieurs tables avec un nombre important de lignes.
Quel est le degré de sélectivité de cet indice? Si votre table a un million de lignes et que sa valeur en atteint cent cinquante mille, alors votre index est inutile. En fait, il peut être pire qu'inutile s'il est réellement utilisé. Rappelez-vous qu’un DELETE est semblable à une instruction SELECT: nous pouvons ajuster son chemin d’accès.
En outre, les suppressions occupent beaucoup de tablespace annulé, de sorte que vous pourriez être victime de conflits, si le système connaît une utilisation intensive. Sur 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 sur ON DELETE CASCADE?
Edit: Compte tenu de tout ce que vous dites, et en particulier de la colonne en question constituant la clé primaire, vous essayez donc de supprimer une seule ligne. Si cela prend beaucoup de temps, il est beaucoup plus probable qu'un autre processus ou utilisateur a un verrou sur la rangée. Est-ce que quelque chose apparaît dans V$LOCK
?
Si quelque chose est lent et que vous ne savez pas pourquoi, tracez-le et découvrez-le.
Comment résoudre les problèmes de performances avec une instruction Oracle SQL
Donc, je vais juste poster mon expérience. Cela 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 secondes suppression de 1 700 enregistrements sur 2 300 dans le tableau foo
.
J'ai vérifié tous les index sur les clés étrangères comme indiqué dans les 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
en in
et utilisé minus
pour obtenir un résultat correct.
Maintenant, la requête s'exécute en 0.04 seconde.
Votre table contient plus de nombre d'enregistrements?
Existe-t-il des programmes récursifs (des boucles imbriquées, etc.) exécutés sur le serveur de base de données?
Vérifiez les problèmes de réseau si le serveur de base de données est sur différentes machines?