IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes PostgreSQL Discussion :

une requête de suppression qui ne fonctionne pas (trop longue)


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 386
    Points : 859
    Points
    859
    Par défaut une requête de suppression qui ne fonctionne pas (trop longue)
    bonjour,

    j'ai une table avec un shéma très simpe :

    id serial NOT NULL,
    wkf_id integer,
    uid integer,
    res_id integer,
    res_type character varying(64),
    state character varying(32) DEFAULT 'active'::character varying,
    CONSTRAINT wkf_instance_pkey PRIMARY KEY (id),
    CONSTRAINT wkf_instance_wkf_id_fkey FOREIGN KEY (wkf_id)
    REFERENCES wkf (id) MATCH SIMPLE
    ON UPDATE NO ACTION ON DELETE SET NULL
    )
    WITHOUT OIDS;
    je souhaite exécuter cette requête :

    delete from wkf_instance where res_type='cpn.account.hour'
    et elle prend plus de 5min voire plus car j'ai arrêté le process croyant que ça plante (cpu à 100%)

    il ya dans la table 700000 enregistrement à supprimer.
    La table fait 56M, l'index 13M alors que le serveur est puissant et à 2go de mémoire.

    où est le problème ?

    si ça peut aider, voilà quelques infos durant le process :





  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Que dit l'EXPLAIN de la requête?

  3. #3
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 386
    Points : 859
    Points
    859
    Par défaut
    Citation Envoyé par estofilo Voir le message
    Que dit l'EXPLAIN de la requête?
    comme elle ne se termine pas, je ne peux pas avoir l'explain analyse !

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    c'est pourquoi il faut faire EXPLAIN delete... et non EXPLAIN ANALYZE delete...

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Est-ce qu'il y a des clefs étrangères qui pointent vers la table dont les lignes sont supprimées par la requête?

  6. #6
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    Comme le dit estofilo, regarde l'explain de ta requête, si ça se trouve il fait un index range scan sur un index inapproprié
    Peut-être aussi as-tu trop d'indexes sur cette table, dans ce cas la suppression de lignes est longue car doit aussi mettre à jour les indexes
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  7. #7
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 386
    Points : 859
    Points
    859
    Par défaut
    bonjour,

    j'ai fait un explain mais pour 50 éléments, voiçi le résultat (ça dure 30s sans le analyse) :

    "Nested Loop (cost=1.78..3155.99 rows=48 width=6)"
    " -> HashAggregate (cost=1.78..2.28 rows=50 width=4)"
    " -> Limit (cost=0.00..1.15 rows=50 width=4)"
    " -> Seq Scan on wkf_instance (cost=0.00..14736.52 rows=639397 width=4)"
    " Filter: ((res_type)::text = 'cpn.account.hour'::text)"
    " -> Index Scan using wkf_instance_pkey on wkf_instance (cost=0.00..63.06 rows=1 width=10)"
    " Index Cond: (wkf_instance.id = "outer".id)"
    " Filter: ((res_type)::text = 'cpn.account.hour'::text)"
    oui il ya 5 tables qui sont ratachées à cette table.

    ps : j'ai regardé la doc, mais ya pas moyen de ajouter une clause LIMIT dans le delete ? je voudrais les supprimer 10 par 10 chaque minute.

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 760
    Points : 52 541
    Points
    52 541
    Billets dans le blog
    5
    Par défaut
    1) rien ne vous empêche de calculer un nombre approximatif de DELETE en jouant sur l'auto incrément. Il n'y a pas de LIMIT avec PostGreSQL pour la mise à jour.
    2) tentez un index en hash sur (res_type, wkf_id )
    3) si vous faites vos DELETE aux heures creuses, une technique consiste à :
    • démarrez une transaction au niveau SERIALIZABLE
    • supprimer tous les index non sémantiques
    • faire votre DELETE
    • rétablir les index
    • valider la transaction



    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    A propos du temps d'exécution, si on synthétise les infos de la discussion:
    - 700000 lignes à effacer dans une table wkf_instance
    - 5 tables référencent wkf_instance en clef étrangère
    - une clause ON DELETE SET NULL sur des tables qui référencent wkf_instance

    Pour chaque ligne à effaçer, postgres doit lancer en interne 5 recherches dans les tables "fille" et pour chaque ligne trouvée dans ces tables, faire un UPDATE d'une colonne à NULL.

    Ca représente donc 700k*5 = 3,5 millions de requêtes SELECT + un nombre de requêtes UPDATE supposément de même ordre de grandeur, ce qui explique pourquoi c'est lent.

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Citation Envoyé par Michael REMY Voir le message
    ps : j'ai regardé la doc, mais ya pas moyen de ajouter une clause LIMIT dans le delete ? je voudrais les supprimer 10 par 10 chaque minute.
    La technique classique est de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     DELETE FROM table WHERE clef_primaire in
     (SELECT clef_primaire FROM table WHERE ... LIMIT 10)

Discussions similaires

  1. Une requête pourtant simple qui ne marche pas
    Par JeanNoel53 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 13/12/2010, 18h30
  2. Réponses: 7
    Dernier message: 23/11/2010, 17h15
  3. Réponses: 21
    Dernier message: 28/06/2010, 08h40
  4. requête de selection qui ne fonctionne pas
    Par emmablue dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 28/07/2006, 13h55
  5. [ODBC] une requete d'insertion qui ne fonctionne pas
    Par boulhous dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 26/05/2006, 13h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo