requete imbriquée

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : requete imbriquée

par jobrider » 13 mai 2009, 10:10

salut,

voici la requete que j'ai testé sans succès..
$result_insert=mysql_query("DELETE A.* FROM matable A JOIN matable2 B ON A.id_email = B.id_email");

j'ai laissé tourné la1ere requete cette nuit et c'est bon finallement, j'aurai du mettre un compteur pour moi le temps necessaire au final..

merci

par Nagol » 13 mai 2009, 00:44

set_time_limit aussi pourrais t'aider tu cherches à nettoyer une table, ca n'a pas besoin d'etre optimisé si ce n'est pas une action utilisateur.

par sadeq » 12 mai 2009, 22:07

Peux-tu donner la requête que tu as écrit ?

par jobrider » 12 mai 2009, 19:06

salut,
je savais qu'on pouvais faire un JOIN avec un delete ?!
mais j'ai essayé : ça me supprime tout sur tablea en mois d'une seconde chorno, pour le coup c'est super otpimisé mais c'est pas le résultat escompté..
:roll:

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

par sadeq » 12 mai 2009, 12:37

Déjà pour optimiser on peut modifier la requête:

Code : Tout sélectionner

DELETE FROM tablea WHERE email IN (SELECT email FROM tableb)
En la récrivant comme ça:

Code : Tout sélectionner

DELETE FROM tablea WHERE id_email IN (SELECT DISTINCT id_email FROM tableb)
Pour utiliser id_email qui est un index numérique au lieu du champ "email" qui est un texte, on gagne du temps quant à la recherche effectuée par WHERE et IN, car la recherche d'un index numérique est plus rapide que celle d'un index de type texte.
Et on peut ajouter une limite pour le nombre de suppression, mais le mot LIMIT doit être à la fin de la commande DELETE:

Code : Tout sélectionner

DELETE FROM tablea WHERE id_email IN (SELECT DISTINCT id_email FROM tableb) LIMIT 20
Ici, seules 20 suppressions max sont autorisées.

En suite, on peut abandonner l'opérateur IN qui oblige la requête de chercher dans un ensemble. Ce qui oblige le moteur de requête à construire d'abord l'ensemble (SELECT ....) avant de faire la recherche IN.
Pour cela, on remplace IN par une jointure naturelle (relation) : JOIN entre les 2 tables, ce qui donne la requête suivante:

Code : Tout sélectionner

DELETE A.* FROM tablea A JOIN tableb B ON A.id_email = B.id_email
La spécification de A.* dans la commande DELETE est obligatoire dans notre cas car elle désigne la table où sera effectuée la suppression puisque dans le FROM on utilise au moins 2 tables liées A et B.
Remarque: Dans cette solution de jointure, le DELETE ne supporte pas le mot LIMIT dans une requête multi-tables.

par jobrider » 12 mai 2009, 09:50

super,
merci albat
je travaille avec de tables test sur phpmyadmin donc je peux manipuler comme je veux.
Les 2 tables sont déjà dédoublonnées, par contre elles ce n'est pas le cas, et c'ets ce que je souhaite faire. Les tables ont chacune les champs suivants :
id_email int(10)
email varchar(200) latin1_swedish_ci

y'a pourtant pas beaucoup de champs..
Je vais essayer avec un select plutot qu'un delete.

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

par albat » 11 mai 2009, 20:53

Salut Pierre-Alain, ;)

La requête que tu utilises est correcte syntaxiquement,
mais au niveau de l'optimisation, comme tu l'as remarqué, c'est épouvantable.

En général, lorsque l'on se retrouve dans une situation de ce type,
c'est imputable à un défaut de modélisation de la base de données.
L'idéal est alors de reprendre son modèle et de le corriger.
Mais ce n'est pas toujours possible.

Je te propose l'astuce suivante,
mais j'ignore si elle est applicable dans ton cas.

1. Fusionner les tables A et B en une seule table.
2. Supprimer les doublons de cette table.

par jobrider » 11 mai 2009, 18:10

merci
j'ai un souci j'ai 35000 email dans tablea et 66000 email dans la tableb.. le script tourne pendant + de 10 minutes et forcément j'abandonne.. qu'est ce que je peux faire..
attendre encore? j'ai essayé de poser un LIMIT 20 et rien n'y fait le script tourne en rond..

$result_insert=mysql_query("DELETE FROM tableb WHERE email IN (SELECT email FROM tableb) LIMIT 20");

par sadeq » 11 mai 2009, 16:30

DELETE FROM tablea WHERE email IN (SELECT email FROM tableb);
Oui, cette requête fait l'affaire.

par albat » 11 mai 2009, 16:13

Modération :
Afin d'obtenir plus de réponses, le sujet est déplacé dans le forum "SQL & Bases de données".

Merci de prendre le temps de lire les règlements
ainsi que l'intitulé de chaque forum avant de poster un nouveau sujet.

requete imbriquée

par jobrider » 11 mai 2009, 15:33

salut à tous,
je cherche à supprimer tous les email de la table a qui sont identiques à la table b

est-ce que la requête suivante est correct ? (j'ai pas testé encore car je traite + de 50000 email et le traitement va être assez long)

DELETE FROM tablea WHERE email IN (SELECT email FROM tableb);

merci pour votre aide