Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/09/2008, 16h11   #1
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 190
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 190
Points : 32
Points : 32
Par défaut Afficher le dernier enregistrement d'une table

Bonjour à tous,

Je souhaite optimiser ma requete sql en traitent et en affichant juste le dernier enregistrement qui a été fait sur ma table.

Données:

Code :
1
2
3
4
5
6
7
id   livreid  auteur     
1    456     jules
2    232     pierre
3    666     gilbert
4    666     jules
5    666     marc
6    185     michel
Ce qui m'interesse, c'est le dernier enregistrement, soit le livreid 666 avec l'auteur marc et ayant l'id 5.

En fait, j'ai 520 livreid portant le numéro 666,mais dans l'exemple j'ai limité à 3 pour faire simple.

Donc, au lieu de scaner tous les 520 enregistrements alors qu'il ya juste le dernier enregistrement qui m'interesse, j'ai décidé d'optimiser la requete en utilisant la commande mysql suivante:

SELECT distinct livreid FROM livres where livreid=666 ORDER BY id Desc limit 1

mais quand je fait un EXPLAIN:

Code :
1
2
3
4
5
id  select_type  TABLE 	 type 	possible_keys 	 KEY       key_len      ref         
1   SIMPLE        livres   ref      livreid             livreid      3            const                      
 
rows  Extra
520   USING INDEX
je vois que sql traite tous mes 520 enregistrements pour examiner et en afficher juste un , ce que je trouve comme étant une perte de temps et une consomation de mémoire inutile.

Avez-vous une meilleure idée pour optimiser davantage le traitement, étant donné que je veux juste traiter et retourner juste un enregistrement.

Pour info: id et livreid sont indexés (id=Primary and livreid=index) .

Merci
persia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2008, 17h41   #2
Membre Expert
 
Avatar de fregolo52
 
Homme
Développeur C
Inscription : août 2004
Messages : 1 460
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur C

Informations forums :
Inscription : août 2004
Messages : 1 460
Points : 2 070
Points : 2 070
Salut,

Peux-tu nous dire que ce que tu entends par "le dernier enregistrement qui a été fait sur ma table"

Est ce :
- le dernier ajout ?
- le dernier modifié ?
fregolo52 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2008, 18h27   #3
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 190
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 190
Points : 32
Points : 32
Citation:
Envoyé par fregolo52 Voir le message
Est ce :
- le dernier ajout ?
- le dernier modifié ?
Désolé, j'aurais du spécifier. C'est le dernier ajout.

Merci
persia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2008, 19h00   #4
Membre Expert
 
Avatar de Sivrît
 
Inscription : février 2006
Messages : 953
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 953
Points : 1 189
Points : 1 189
Citation:
Envoyé par persia Voir le message
je vois que sql traite tous mes 520 enregistrements pour examiner et en afficher juste un , ce que je trouve comme étant une perte de temps et une consomation de mémoire inutile.
En fait c'est peut-être déjà optimal. "USING INDEX" c'est bien (si j'interprète bien on ne va rien lire dans la table), et comme c'est le seul commentaire ça laisse penser que le tri passe bien par l'index aussi. Le "520" est à prendre avec de pincettes car c'est une estimation de ce que MySQL s'attend à trouver. Ce n'est pas forcément exact, et je ne sais pas si ça prend le LIMIT en compte.

Je dirais juste que le "distinct" est de trop mais ça n'a pas l'air de déranger ici.

Citation:
Envoyé par persia Voir le message
Avez-vous une meilleure idée pour optimiser davantage le traitement, étant donné que je veux juste traiter et retourner juste un enregistrement.

Pour info: id et livreid sont indexés (id=Primary and livreid=index) .
L'index parfait serait (livreid, id). Ca permet de chercher le livreid, puis d'utiliser les id triés pour prendre le plus grand. Seulement avec InnoDb la clef primaire est ajoutée à la fin des indexes normaux (c'est somme toute le résultat) donc il ne doit pas y avoir de différence (ou alors vraiment subtil) entre indexer (livreid) ou (livreid, id) qui n'aurait de toute façon pas grand intérêt.

Bref d'après le explain ça a l'air pas mal.
Sivrît est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2008, 19h59   #5
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 190
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 190
Points : 32
Points : 32
Citation:
Envoyé par Sivrît Voir le message
(si j'interprète bien on ne va rien lire dans la table)
Si, il faut lire l'enregistrement dans la table pour ensuite l'afficher. (Mais juste 1)

Citation:
L'index parfait serait (livreid, id).
J'ai déjà essayé, mais pas un grand changement, voire aucun.

Ce que j'ai remarqué, c'est que ça prenait beaucoup de temps pour que la page se charge(page php) lorsque je fait un tri par numéro d'id ou peut importe la colonne.
Quand j'enlève le tri, le résultat s'affiche 10 fois plus rapidement que lorsque je passe par un tri.

C'est normal je trouve, car sql va aller comparer élément par élément pour aller chercher le dernier enregistrement.

Est-ce qu'il n'y aurai pas un autre moyen plus optimisé pour aller directement chercher le dernier enregistrement (le dernier ajout)?

Merci
persia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2008, 21h58   #6
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 034
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 034
Points : 18 326
Points : 18 326
Envoyer un message via MSN à CinePhil
A essayer :
Code :
1
2
3
4
SELECT id, livreid, auteur
FROM livres
GROUP BY livreid
HAVING id = MAX(id)
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 00h53   #7
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 190
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 190
Points : 32
Points : 32
Citation:
Envoyé par CinePhil Voir le message
A essayer :
Code :
1
2
3
4
SELECT id, livreid, auteur
FROM livres
GROUP BY livreid
HAVING id = MAX(id)
Aucun changement.

J'ai ajouté une clause where et une limit, car ce qui m'interesse c'est le livreid:666.

Code :
1
2
3
4
5
SELECT id, livreid, auteur
FROM livres
WHERE livreid=666
GROUP BY livreid
HAVING id = MAX(id)
Mais ca me retourne le premier enregistrement et non le dernier.




Merci
persia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 19h03   #8
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 190
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 190
Points : 32
Points : 32
J'ai essayé la commande suivante:

Code :
SELECT max(id) FROM livres WHERE livreid=666.
ça marche, mais qu'en est-t'il si je veux afficher le nom de l'auteur en plus de l'id , ou bien tout simplement l'auteur associé au livreid 666?.

Si je fait un group by, ca me retourne tous les éléments, ce que je veux éviter.

Merci
persia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/09/2008, 19h26   #9
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 034
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 034
Points : 18 326
Points : 18 326
Envoyer un message via MSN à CinePhil
Code :
1
2
3
4
5
6
7
SELECT auteur, id AS MaxId, 
FROM livres
WHERE id = (
  SELECT MAX(id)
  FROM livres
  WHERE livreid = 666
)
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h19.


 
 
 
 
Partenaires

Hébergement Web