Mettre un index pour un ORDER BY ?

ViPHP
AB
ViPHP | 5818 Messages

24 févr. 2011, 19:32

Au fait pour t'en rendre compte devlop78 t'avais suggérer de faire un explain, tu l'a fait ?
$SQL = "EXPLAIN SELECT * FROM forum_messages WHERE id_topic = '1' ORDER BY date ASC";

mysql_select_db(...);

$Result = mysql_query($SQL) or die(mysql_error());

while ($assoc = mysql_fetch_assoc($Result))
{
echo '<pre>';
print_r($assoc);
echo '</pre>';
}
Et les explications pour lire le résultat est là

Eléphanteau du PHP | 33 Messages

24 févr. 2011, 19:56

Bon ok c'est bien ce que je pensais à l'origine alors.
Dans ton msg de 16:55 tu disais " seul l'index sur le champ de la clause WHERE sera utilisé et ton index double ne servira pas pour cette requête" par ce que tu pensais que je parlais de pas avoir besoin du ORDER BY.

En faite je parlais juste du ORDER BY id_topic qui était inutile.
Le ORDER BY date lui m'est utile.

J'ai fait le EXPLAIN pour tester et mon double index est bel et bien utilisé dans ma requête donnée au tout début.

ViPHP
AB
ViPHP | 5818 Messages

24 févr. 2011, 21:13

J'ai fait le EXPLAIN pour tester et mon double index est bel et bien utilisé dans ma requête donnée au tout début.
Comme quoi, un EXPLAIN vaut mieux qu'un long discours :wink:

ViPHP
ViPHP | 2577 Messages

28 févr. 2011, 10:49

Bonjour,

En fait dans l'idée, je pensais que mettre where id=1 order by id,date permettait d'utiliser l'index double pour le where et pour le order by sans changer le résultat puisque id est unique lorsque traité pour le order by.

Il faut que j'apprenne à me servir du explain.

Pour info, je pense que le explain donne des résultats différents en fonction du contenu de la base (nombre de lignes et nombre de valeurs différentes dans les colonnes. Je dis ca à cause de DB2 qui utilise une pré-compilation des ordres SQL qui doit être refaite en cas de grosse modification du contenu des tables en général et lors du passage des programmes d'un environnement de test à un environnement de production.

devlop78
Invité n'ayant pas de compte PHPfrance

01 mars 2011, 21:44

Pour info, je pense que le explain donne des résultats différents en fonction du contenu de la base
Bon, comme je suis nul en optimisation de requête mais que j'ai envie de faire ma grosse tête ce soir, je vais rajouter : Oui, le explain peut changer. Car l'optimiseur fait un peu à sa guise en terme d'execution de ta requête. Il est dit qu'il optimise plutôt bien ^^, mais il a le choix dans l'ordre de lecture des tables sur des jointures, il a le choix aussi d'utiliser ou non les index. Ce n'est pas parce que tu les as créées, qu'il va les utiliser. Tu peux, par contre, l'obliger à lire des tables dans un ordre précis, tout comme tu peux le forcer à utiliser, ou non, les index.

Pour ce qui est des ORDER BY, je pense, mais je ne connais pas vraiment le contexte, qu'il s'agit d'une redondance. Car j'imagine que l'identifiant de tes topics repose sur une clé primaire, et qu'un topic qui a un identifiant supérieur à un autre est toujours plus récent. Donc, trier par identifiant, revient à trier par date. Donc, il est important que l'un ou/et l'autre soit indexé. Après index double ou pas ... je laisse l'avis à d'autre, j'utilise très fréquemment des index multiples, mais de souvenirs, que pour des UNIQUE.

Dans l'absolu, j'aurais tendance à dire que partout où il y a une clause where, une clause order by, et un group by, il y a un index. Mais rien n'est sûr là dessus, puisque les deux derniers sont executés après la sélection des lignes, donc à voir s'il utilise les index (le explain ...).

Regarde aussi du coté de developpez.com, il y a des ouvrages PDF gratuits sur l'optimisation des requêtes, dont SQLPro qui en a écrit un. Pour ma part, l'optimisation n'est pas priorité au vu des applications que je crée, même si c'est important, ma priorité se porte sur les comportements de cohérence, plus globalement ACID. Ensuite, je réfléchis à exécuter le moins de requêtes possibles, et j'ai été très désagréablement surpris de voir ce que j'appellerais une faiblesse en matière de retour d'erreur MySQL, concernant les contraintes. Je suis donc obligé de faire des SELECT avant des INSERT, ce que je trouve un peu idiot étant donné que pour des raisons de cohérences, MySQL effectue lui-même les SELECT nécessaire et me renvoie une erreur si une contrainte est violée. Erreur que je ne sais exploiter sans bricolage, ce que je me refuse. Mais là, c'est une autre histoire, cette petite parenthèse peut toujours essayer de te convaincre d'utiliser les FK (foreign Key), qui te permettront d'éviter d'avoir des id_topics inexistants, entre autres, et d'éviter si tu choisis le CASCADE, d'avoir à faire plusieurs DELETE, source de codes et surtout d'erreurs dûes à des oublies ... à des problèmes par la non utilisation de transaction, etc ...

A+