J'ai actuellement une requête plutôt complexe qui est trop lente.
Explication de l'utilité de la requête:
J'ai actuellement un jeu en ligne, dans lequel les joueurs ont un historiques des évènements, une sorte de liste de messages d'autres joueurs. Chaque message peut avoir un ou plusieurs envoyeurs et destinataire.
Le jeu offre la possibilité de renommer chaque connaissance (personnage). À la base, tous le monde est donc inconnu, ou inconnue si le sexe du personnage est féminin.
La requête:
Je l'ai laissée en PHP
Je possède 2 tables assez immenses:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 $query = 'SELECT he.msg, he.date, he.id AS hid, he.type,' . ' pc.nom, ft.fromto, ft.persoid,' . ' p.sexe, p.imgurl, ft.`show`' . ' FROM (' . 'SELECT msgid, `show`' . ' FROM he_fromto' . ' WHERE `show`!=0' . ' AND persoid = ' . (int)$perso->getId() . ' ORDER BY `msgid` DESC' . ' LIMIT ' . (int)$from . ',' . (int)$nbr . ') as sq' . ' INNER JOIN he AS he ON (he.id=sq.msgid)' . ' INNER JOIN he_fromto AS ft ON ( ft.msgid = he.id )' . ' LEFT JOIN perso_connu AS pc' . ' ON (pc.persoid = ' . (int)$perso->getId() . ' AND pc.nomid = ft.persoid )' . ' LEFT JOIN perso AS p' . ' ON ( p.id = ft.persoid )' . ' ORDER BY he.`date` DESC, hid ASC, ft.fromto ASC , pc.nom ASC;';
he, qui contient tous les messages
he_fromto, qui contient tous les informations sur les envoyeurs ou les destinataire (champs `fromto`: from ou to). Cette table détermine aussi qui sont les joueurs qui ont effacés le message de leur historique des évènements (champ `show`). Lorsque tous les joueurs ont effacé le message, celui-ci est réellement supprimé.
But:
Je cherche donc à optimiser cette requête car elle prend parfois plusieurs secondes à être exécuté: beaucoup trop long !
En la regardant, j'ai réalisé que les jointures devaient logiquement faire des full table scan, et qu'il serait intéressant de les limiter:
INNER JOIN he AS he, il n'y a qu'un seul message par ligne de sq (message à afficher)
LEFT JOIN perso_connu AS pc, il n'y a qu'un seul personnage connu par ligne de ft (destinataire ou envoyeur)
LEFT JOIN perso AS p, il n'y a qu'un seul personnage par ligne de pc (perso connu)
Je demeure ouvert à toute suggestions qui ne demandent pas de chambouler trop de choses (vu que c'est la page principale du site, le coeur du moteur de jeu, et que plusieurs milliers de lignes reposent sur cette structure)
Merci à tous ceux qui ont pris la peine de me lire, j'espère avoir été plus clair que pénible à lire
Partager