J'ai le tableau 1: les utilisateurs
SELECT u.id, u.name, p.title FROM users AS u LEFT JOIN posts AS p ON p.user_id= u.id WHERE p.posted = ( SELECT MAX(posted) FROM posts WHERE user_id = u.id ) ORDER BY u.id LIMIT 15
Et le tableau deux appelé posts:
id | user_id | title | posted 1 | 1 | Something | 1551128761 2 | 1 | Else | 1551128761 3 | 3 | Some Title | 1551122745 4 | 2 | Demo Title | 1551129777 5 | 3 | Something | 1551126793
user_id dans le deuxième tableau est l'id de l'utilisateur du premier tableau
J'ai besoin de sortir le dernier message du tableau et je le fais actuellement en utilisant cette requête:
id | name | 1 | john | 2 | garry| 3 | sam |
Mais le problème avec cette requête est que si l'horodatage est le même pour le même utilisateur (dans cet exemple pour l'utilisateur avec user_id 1 , l'horodatage est le même), j'obtiens ces deux lignes à la place du dernier (le dernier a l'ID le plus élevé)
3 Réponses :
Essayez cette requête MySQL:
ALTER TABLE posts ADD INDEX(user_id); ALTER TABLE posts ADD INDEX(posted);
Testé et fonctionne très bien. Voici une démo: DBFiddle
indexesSELECT u.id,
u.name,
p.title
FROM users AS u
JOIN posts AS p
ON p.id = (SELECT pi.id
FROM posts AS pi
WHERE pi.user_id = u.id
ORDER BY pi.id DESC
LIMIT 1);
8000 comme pour le moment - cela prend environ 2 secondes avec mon ancien et environ 25 secondes avec celui-ci, mais le vôtre fait vraiment ce dont j'ai besoin
Suggestion: l'index utile est sur les articles (user_id, posté, id) .. essayez d'indexer et vérifiez à nouveau la vitesse
comment dois-je faire ça?
Si vous utilisez PHPMyAdmin pour afficher la structure de votre table, vous devriez pouvoir voir différents onglets en cliquant sur un nom de table. Cliquez sur Structure> Index dans chaque ligne pour ajouter des index sinon exécutez des requêtes SQL pour les trois colonnes comme celle-ci: ALTER TABLE posts ADD INDEX (user_id);
Ok, je l'ai fait comme tu l'as dit, ça va plus vite que jamais, merci!
Petite question, id n'est-il pas déjà indexé? (c'est la clé primaire et incrémentée automatiquement)
Oui, pas besoin d'ajouter un index sur les clés primaires - elles sont déjà indexées :)
un index fonctionnera-t-il si les données de la colonne ne sont pas uniques?
Que diriez-vous de restructurer légèrement la requête?
SELECT posts.title, users.id, users.name FROM posts, users WHERE posts.user_id = users.id ORDER BY posts.posted DESC, posts.id DESC LIMIT 1
Essentiellement en sélectionnant parmi les articles, en triant par l'horodatage publié et deuxièmement par l ' id de le message dans l'ordre décroissant au cas où l'horodatage serait le même.
Une option utilisant la colonne id de la table des articles comme suit. Cela suppose que l'identifiant sera différent pour chaque enregistrement de publication dans la table des publications. Démo ici
SELECT u.id, u.name, p.title,p.posted FROM users AS u LEFT JOIN posts AS p ON p.user_id= u.id WHERE (p.posted,p.id) = ( SELECT MAX(posted),MAX(id) FROM posts WHERE user_id = u.id ) ORDER BY u.id
salut @vmaroli, cela fonctionne mais cela prend le temps de requête de 2 secondes à ~ 25 secondes :(
La colonne id est-elle la clé primaire ou possède-t-elle un index unique dans la table des publications? Si votre identifiant pour les publications est unique et garanti dans un ordre croissant, vous pouvez filtrer par identifiant au lieu de l'horodatage. Voir dbfiddle.uk/... Cela devrait donner de bien meilleures performances car il s'agit d'un accès par index / clé primaire unique
La colonne id est un auto_increment unique pour les deux tables. dans le post de table, j'identifie les messages / utilisateur par user_id qui peut être plus d'un (pas unique) - pour chaque message publié par cet utilisateur
Alors le SQL mentionné dans mon commentaire précédent devrait fonctionner correctement? Étant donné que son accès à l'aide de la clé primaire doit également être rapide.
Oui, c'est le cas et je l'utilise. J'ai juste utilisé celui ci-dessus en premier jusqu'à ce que j'aie atteint celui-ci, donc j'ai déjà "préféré" celui-là. Mais encore une fois, j'utilise celui-ci
ON p.ticker_id = u.idne devrait-il pas êtreON p.user_id = u.id?@Utkanos modifier l'erreur, merci
J'ai les données devant moi et j'obtiens ces deux lignes, mais si j'ajoute une seconde à l'une ou l'autre de ces deux lignes, je n'en reçois qu'une (ce qui est exactement ce dont j'ai besoin
Essayez
DISTINCTdans votre partie de sélection, avantu.id