JeuWeb - Crée ton jeu par navigateur
Modifier plusieurs entrées en une seule requête UPDATE avec MySQL - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Modifier plusieurs entrées en une seule requête UPDATE avec MySQL (/showthread.php?tid=5113)

Pages : 1 2


Modifier plusieurs entrées en une seule requête UPDATE avec MySQL - php_addict - 26-08-2010

bonjour à tous, j'espère que vous allez bien.

je sollicite une nouvelle fois votre aide pour un probleme tout bête, celui de la lenteur de la requete UPDATE.

dans ma messagerie privée j'ai la liste des messages reçus avec des checkboxes pour pouvoir sélectionner tout les messages recus afin de les effacer...

les messages ne sont pas réellement effacés de la base de données mais il y a un UPDATE (genre lu='1' )

ma requete tourne donc en boucle sur tout les messages selectionnés:
Code PHP :
<?php 
UPDATE mp_etat SET del
='1' WHERE id='$id' AND dest='$id_joueur'

j'ai bien mis un index sur id et sur dest. et même un index sur ces 2 colonnes...

mais j'ai testé avec 100 messages à supprimer et cela me prends 6 secondes...

il me semble que les UPDATE multiples (comme pour INSERT) ne sont pas possibles en MySQL

auriez vous une idée lumineuse (à part celle de ne pouvoir sélectionner que 10 messages seulement par exemple Wink )

bon apres midi


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - Sephi-Chan - 26-08-2010

Récupère plutôt l'ID des messages sélectionnés et regroupe les pour générer une clause IN().

Pour avoir directement un tableau d'ID, met directement un nom de la forme suivante à tes check boxes :


<input type="checkbox" id="delete-message-12" value ="12" name="messages_to_delete[]" />
<input type="checkbox" id="delete-message-19" value ="19" name="messages_to_delete[]" />

Ainsi, ta variable $_POST[messages_to_delete] contiendra un tableau de chaînes de caractères numériques), ensuite, tu n'as plus qu'à construire une requête de la façon suivante (n'oublie pas qu'on encadre pas les entiers de guillemets en SQL) :


$message_ids = array_filter($_POST['messages_to_delete'], 'is_numeric');

$query = sprintf(
"UPDATE mp_etet SET del = 1 WHERE id IN(%s) AND dest = %d;",
join(', ', $message_ids),
$id_joueur
);

Et ça te produira une requête comme :


UPDATE mp_etet SET del = 1 WHERE id IN(12, 19) AND dest = 42;

Je n'ai pas testé mais ça devrait le faire.


Sephi-Chan


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - php_addict - 26-08-2010

merci, j'suis c@n...pas pensé à la clause IN() ...

ca fonctionne mieux comme ca évidement :$

(26-08-2010, 03:55 PM)Sephi-Chan a écrit : (n'oublie pas qu'on encadre pas les entiers de guillemets en SQL) :

je me demande pourquoi? il faut que je revois mes requêtes, j'entoure tout tout le temps...

encore merci une fois de plus Wink


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - Sephi-Chan - 26-08-2010

Parce que seules les chaînes de caractères sont encadrées de guillemets (et en SQL, ce sont des guillemets simples), ça inclut les dates.

Est-ce que tu utilisais l'astuce du nommage des check boxes ? Car l'astuce repose là dessus et sur l'utilisation du array_filter. Le IN est secondaire. :p


Par contre, merci d'utiliser les tags présentés juste à côté du champ de texte du titre.

Et pense aussi à formuler correctement ton titre : ici tu as appelé ton sujet "refonte de ma messagerie privée, un dernier soucis de lenteur d'update", ça ne vaut pas mieux que "problem help plz".

Si tu avais bien formulé ton titre, tu aurais mieux cerné ton besoin, à savoir modifier plusieurs champs d'un seul coup, et ça t'aurait peut-être aidé. Wink


Sephi-Chan


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - Ter Rowan - 26-08-2010

deux points tout de même (bien que pas expert)

Primo
Avec un in, il y a une limitation du nombre "d'items" que tu peux lui mettre dedans (j'ignore en fait si c'est le nombre ou le nombre de caractères, mais bref).

Tu dois donc t'assurer par algorithme que le nombre d'items ne dépasse pas une limite que tu fixeras (de mémoire la limite est à 1000 pour Oracle, mais c'est vraiment de mémoire) le mieux est de définir une constante/paramètre/élément de configuration ce sera plus facile à modifier

Secundo
Si tu n'utilises pas de in pour x raisons, en utilisant PDO tu dois pouvoir t'appuyer sur les requêtes préparées qui devraient (mais je n'ai pas testé) optimiser le traitement.


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - Sephi-Chan - 26-08-2010

Moi j'veux bien une source pour le IN (pour Oracle et surtout pour MySQL puisque c'est celui qui importe ici), car je n'ai jamais entendu parler de ça. Malgré tout le respect que j'ai pour ta mémoire, c'est un point suffisamment important pour ne pas se fier à une vague souvenir. :p

D'après la documentation de la fonction IN de MySQL, on a bien une limite définie par la variable max_allowed_packet (définie dans le fichier de configuration de MySQL (my.cnf) ou surchargée en ligne de commande ou via la commande SET).

D'après moi, cette limite est suffisamment haute pour être ignorée (quelque chose d'autre craquera avant) puisqu'on parle tout de même d'un blob de 1Go.


Sephi-Chan


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - Ter Rowan - 26-08-2010

google est ton ami ^^

http://www.experts-exchange.com/Database/Oracle/Q_20964987.html

pour oracle


pour mysql je n'ai jamais essayé
à noter je parle bien de limitation d'un in ( v1, v2, v3, ...)
pas d'un in (select ...)


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - Sephi-Chan - 26-08-2010

Enfin quand on annonce un truc qui peut être important, c'est bien d'apporter un soupçon de source. Wink
Et le lien que vers Experts Exchange… La question je la connais, c'est la réponse que je veux. Et elle n'est pas donnée. :/

M'enfin la réponse serait probablement dans le même goût de celle de MySQL. Ce n'est pas à notre niveau qu'on risque de le rencontrer. ^^


Sephi-Chan


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - Ter Rowan - 26-08-2010

bah la réponse était dedans maintenant elle semble être filtrée/payante


dans tous les cas je confirme (puisque j'ai pu lire la réponse) bien la limitation en version 9i à 1000
Oracle, générant un message d'erreur indiquant que la limite de 1000 est dépassée (pour ceux que ça intéresse, ben à eux d'aller chercher la doc en fonction de la version)

maintenant je levais une alerte au vu de mon expérience, c'est tout
tiens un autre lien, ou je suis maudit si on ne le lit pas cette fois

http://dbaforums.org/oracle/index.php?showtopic=17629


RE: refonte de ma messagerie privée, un dernier soucis de lenteur d'update - php_addict - 26-08-2010

(26-08-2010, 04:28 PM)Sephi-Chan a écrit : Est-ce que tu utilisais l'astuce du nommage des check boxes ? Car l'astuce repose là dessus et sur l'utilisation du array_filter. Le IN est secondaire. :p

oui: name="check[]" ce qui me permet aussi de cocher toutes les checkbox en JS (pour une meilleure expérience utilisateur, comme disent les pros Wink )

PS: je renomme le topic.