07-03-2014, 10:15 PM
Je n'avais pas pensé à EXPLAIN... >.>
L'index accélère légèrement, mais ce n'est pas la panacée...
Je viens de tester ta proposition, mais les performances sont mauvaises (là encore, la durée dépassant les 30secondes, je n'ai pas attendu la fin de la requête pour connaitre sa durée réelle). Cela ne me surprend pas d'un coté, car mes souvenirs de cours me disent que les sous-requêtes sont bien plus longues que les jointures, même si on parle d'une seule sous-requête face à 4 jointures. Confirmé en pratique, puisque la requête avec jointures file vite, alors que celle-ci avec la sous-requête traine.
Il me semble d'ailleurs que MySQL exécute la sous-requête pour chaque ligne retournée par la requête parente. Donc, si la requête principale (mer=0 and altitude<=0) renvoie environ 5.000 lignes, le SQL va faire 5.000 fois la sous-requête (EXISTS), ce qui dure... une éternité dirons-nous ^^
Je garderai donc la requête précédente (avec 4 jointures).
Je n'ai pas saisis ton histoire de doublons en revanche. La requête utilisée ne fait pas de doublons?!
(rappel pour éviter de retourner à la page d'avant)
Même principe si j'utilise un SELECT, en récupérant case0.id, case0.x, case0.y par exemple. Bien sûr, si je récupérai "*", j'aurai les données des cases voisins (case1..4), qui donc sont déjà "présentes" ailleurs, en tant que "case0", et j'ai une forme de doublons partiels (aka, des données qui apparaissent dans plusieurs lignes de résultat, mais pas des lignes en double).
Après, pour le changement de structure, ce n'est pas plus mal: je préfère finalement disposer d'une liste des voisins pour chaque case, stockée dans la BDD, plutôt que de me reposer sur des "x+/-1,y+/-1" dans le code PHP. Cela m'arrange d'ailleurs car les bords de carte doivent être gérés différemment. En gardant la structure de map dans le PHP, il me faudrait 1 classe pour les cases normales, 1 pour les cases de la ligne du haut (bord haut de la carte), 1 pour la ligne du bas, 1 à gauche, et 1 à droite...
Donc, changer un poil la structure des tables est plus une avancée qu'une contrainte
L'index accélère légèrement, mais ce n'est pas la panacée...
Je viens de tester ta proposition, mais les performances sont mauvaises (là encore, la durée dépassant les 30secondes, je n'ai pas attendu la fin de la requête pour connaitre sa durée réelle). Cela ne me surprend pas d'un coté, car mes souvenirs de cours me disent que les sous-requêtes sont bien plus longues que les jointures, même si on parle d'une seule sous-requête face à 4 jointures. Confirmé en pratique, puisque la requête avec jointures file vite, alors que celle-ci avec la sous-requête traine.
Il me semble d'ailleurs que MySQL exécute la sous-requête pour chaque ligne retournée par la requête parente. Donc, si la requête principale (mer=0 and altitude<=0) renvoie environ 5.000 lignes, le SQL va faire 5.000 fois la sous-requête (EXISTS), ce qui dure... une éternité dirons-nous ^^
Je garderai donc la requête précédente (avec 4 jointures).
Je n'ai pas saisis ton histoire de doublons en revanche. La requête utilisée ne fait pas de doublons?!
(rappel pour éviter de retourner à la page d'avant)
UPDATE `cases` `case0`
LEFT JOIN `cases` `case1` ON (`case1`.`id`=`case0`.`idVoisin1`)
LEFT JOIN `cases` `case2` ON (`case2`.`id`=`case0`.`idVoisin2`)
LEFT JOIN `cases` `case3` ON (`case3`.`id`=`case0`.`idVoisin3`)
LEFT JOIN `cases` `case4` ON (`case4`.`id`=`case0`.`idVoisin4`)
SET `case0`.`mer`=1
WHERE
`case0`.`mer`=0
AND `case0`.`altitude`<=0
AND (
`case1`.`mer`=1
OR `case2`.`mer`=1
OR `case3`.`mer`=1
OR `case4`.`mer`=1
)
Même principe si j'utilise un SELECT, en récupérant case0.id, case0.x, case0.y par exemple. Bien sûr, si je récupérai "*", j'aurai les données des cases voisins (case1..4), qui donc sont déjà "présentes" ailleurs, en tant que "case0", et j'ai une forme de doublons partiels (aka, des données qui apparaissent dans plusieurs lignes de résultat, mais pas des lignes en double).
Après, pour le changement de structure, ce n'est pas plus mal: je préfère finalement disposer d'une liste des voisins pour chaque case, stockée dans la BDD, plutôt que de me reposer sur des "x+/-1,y+/-1" dans le code PHP. Cela m'arrange d'ailleurs car les bords de carte doivent être gérés différemment. En gardant la structure de map dans le PHP, il me faudrait 1 classe pour les cases normales, 1 pour les cases de la ligne du haut (bord haut de la carte), 1 pour la ligne du bas, 1 à gauche, et 1 à droite...
Donc, changer un poil la structure des tables est plus une avancée qu'une contrainte