Question

Bonjour, j'ai une question que je me bats avec beaucoup, espère que quelqu'un a déjà trouvé une solution intelligente à ce (j'utilise MySQL).

Je table comme ceci:

Table `log`
----------
id
inserted
message
user_id

Mon but est de sélectionner le dernier enregistrement inséré pour l'utilisateur et faire vite. Table Log est énorme (environ 900k records), Ma première approche était:

SELECT * FROM `log` 
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id`
WHERE `id` IN 
(
 SELECT MAX(`id`) FROM `log` GROUP BY `user_id`
)

Mais il semble que ce calcul sous-requête pour chaque ligne (EXPLAIN QUERY DEPENDANT). Lorsque je partage cette requête pour deux:

SELECT MAX(`id`) FROM `log` GROUP BY `user_id`

et

SELECT * FROM `log` 
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id`
WHERE `id` IN (....ids from first query...)

Il est acceptable de fonctionner. Cela peut-il être achived par une requête?

Était-ce utile?

La solution

En plus d'utiliser le groupe pour aller chercher par le maximum de groupe sage, vous voulez probablement faire une sous-requête décorrélée chercher des champs supplémentaires pour les lignes spécifiques de la table.

SELECT
  la.user_id,la.message
FROM
  `log` as la
INNER JOIN
  (
    SELECT
      user_id, MAX(id) AS maxid
    FROM
      `log`
    GROUP BY
      user_id
    ) as lb
ON
  la.id = lb.maxid

Cela fonctionne mieux / plus rapide si vous avez un indice

KEY `foo` (`user_id`,`id`)

mais même sans cette touche la performance est la descente.

Autres conseils

Qu'en est-

SELECT user_id, max(id) FROM `log` GROUP BY user_id

vous obtiendrez l'id maximum pour chaque utilisateur dans la table de journal, en une seule requête!

Si vous êtes à la recherche toujours pour le journal pour un utilisateur particulier, le partitionnement du fichier journal par user_id accélérerait les choses beaucoup. Si la table est partagée par l'utilisateur et indexé par identifiant, la requête sera exécutée très rapidement.

EDIT: voir la requête de Dominik

En outre, je voudrais vous assurer que vous avez un index sur user_id.

EDIT: généralisée

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top