Mettre un index pour un ORDER BY ?

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Mettre un index pour un ORDER BY ?

Re: Mettre un index pour un ORDER BY ?

par devlop78 » 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+

Re: Mettre un index pour un ORDER BY ?

par Mazarini » 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.

Re: Mettre un index pour un ORDER BY ?

par AB » 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:

Re: Mettre un index pour un ORDER BY ?

par aqua007 » 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.

Re: Mettre un index pour un ORDER BY ?

par AB » 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à

Re: Mettre un index pour un ORDER BY ?

par AB » 24 févr. 2011, 19:21

Nan...
L'index double id_topic_date sera utilisé - même si par ailleurs les champs id_topic et date son indexés individuellement - si tu écris :

WHERE id_topic = .. ORDER BY date

Par contre - toujours si les champs id_topic et date son indexés individuellement - seul l'index sur le champ WHERE sera utilisé si tu écris :

WHERE id_topic = ... (sans avoir postérieurement de clause ORDER BY)

et seul l'index sur le champ ORDER BY sera utilisé si tu écris :

ORDER BY date ... (sans avoir préalablement de clause WHERE)

(Evidemment cela suppose que id_topic n'est pas unique dans ta table sinon le ORDER BY ne sert à rien)

Re: Mettre un index pour un ORDER BY ?

par aqua007 » 24 févr. 2011, 18:45

mmm d'accord, je crois que je viens de comprendre.

L'index double (id_topic,date) est utile que si j'ai

WHERE id_topic = .. AND date = ..
ou
ORDER BY id_topic, date

Mais pas utilisé si j'ai WHERE id_topic = .. ORDER BY date

Il faut que les 2 champs de l'index soit au même endroit et pas l'un dans une condition et l'autre dans un tri.
Donc dans mon cas, pas d'utilité d'index double pour ma requête.

Re: Mettre un index pour un ORDER BY ?

par AB » 24 févr. 2011, 16:55

Evidemment si tu n'as pas besoin du ORDER BY dans ta requête, seul l'index sur le champ de la clause WHERE sera utilisé et ton index double ne servira pas pour cette requête.

Re: Mettre un index pour un ORDER BY ?

par aqua007 » 24 févr. 2011, 16:24

Bonjour,
...
SELECT * FROM forum_messages WHERE id_topic = 1 ORDER BY date ASC LIMIT 0,25
...
J'ai un doute sur le fait qu'un sgbd soit capable d'utiliser 2 index sur une table pour une requête.

Pour moi
SELECT * FROM forum_messages WHERE id_topic = 1 ORDER BY id_topic, date ASC LIMIT 0,25
avec un index sur id_topic, date.
Normalement, l'index (d_topic, date) sera utilisé pour le where et pour le order by
C'est pas une perte de temps le ORDER BY id_topic ?
Vu que dans le WHERE je spécifie un seul topic y'a pas de raison de faire un tri ?

Ou alors si on ne le met pas, l'index double (id_topic,date) ne sera pas utilisé ?
Je pensais que si vu que la requête utilise le id_topic dans le WHERE et le date dans le ORDER BY

Re: Mettre un index pour un ORDER BY ?

par AB » 23 févr. 2011, 23:18

Bonjour,
...
SELECT * FROM forum_messages WHERE id_topic = 1 ORDER BY date ASC LIMIT 0,25
...
J'ai un doute sur le fait qu'un sgbd soit capable d'utiliser 2 index sur une table pour une requête.

Pour moi
SELECT * FROM forum_messages WHERE id_topic = 1 ORDER BY id_topic, date ASC LIMIT 0,25
avec un index sur id_topic, date.
Normalement, l'index (d_topic, date) sera utilisé pour le where et pour le order by
Arf tu as raison, j'ai dit des bêtises :oops: Puisque id_topic n'est pas unique, l'index double sera utilisé avec profit.

Re: Mettre un index pour un ORDER BY ?

par Mazarini » 23 févr. 2011, 15:09

Bonjour,
...
SELECT * FROM forum_messages WHERE id_topic = 1 ORDER BY date ASC LIMIT 0,25
...
J'ai un doute sur le fait qu'un sgbd soit capable d'utiliser 2 index sur une table pour une requête.

Pour moi
SELECT * FROM forum_messages WHERE id_topic = 1 ORDER BY id_topic, date ASC LIMIT 0,25
avec un index sur id_topic, date.
Normalement, l'index (d_topic, date) sera utilisé pour le where et pour le order by

Re: Mettre un index pour un ORDER BY ?

par AB » 23 févr. 2011, 04:33

Un index double serait utile si tu n'avais pas déjà indexé individuellement les deux colonnes.

Il y a un peu de doc ici

Re: Mettre un index pour un ORDER BY ?

par aqua007 » 23 févr. 2011, 00:40

J'ai pas en local (trop lourd plusieurs go de sql, trop compliqué car j'ai pas de linux pour le faire tourner et le serv ou il est a plein de truc installés par le mec qui gère les serv comme cache php, gzip et d'autres truc d'optimisation) et en distant la charge est jamais pareil :/ Pis la second fois la requête est cachée.
"cela devrait ralentir ta requête car le chargement des index prend du temps"
Merci de l'info je savais pas.

Je vais nettoyer les index doubles alors si des simples suffises (mais faudrait que je trouve quand même l'interêt d'index doubles);

Re: Mettre un index pour un ORDER BY ?

par AB » 22 févr. 2011, 22:38

Dans ma table forum_message id_topic est bien une clé étrangère faisait référence au champs id de ma table forum_topic. Mais nul par dans myslq je l'ai renseigné (je savais pas que c'était possible), c'est pour ça que j'ai mis actuellement id_topic en INDEX avec aussi un INDEX sur le champs date.
Je dispose de topic très lourds (centaines voir milliers de messages par topic parfois).

Merci déjà pour la confirmation de l'utilisation de l'index sur le ORDER BY.

Après je me demandais si en théorie c'était intéressant de mettre un INDEX comprenant 2 champs, sur les champs id_topic + date (en plus du champs index sur id_topic et du champs index sur date qui eux sont utilisés pour d'autres requêtes par exemple) pour ma requête donnée dans mon premier post en particulier (car c'est elle qui est lente parfois), vu qu'elle utilise ces deux champs la.

Ca doit bien servir à quelque chose de pouvoir faire des index sur plusieurs champs à la fois plutot que de faire autant d'index que je champs.
Et pourquoi tu fais pas des tests ? En local c'est relativement stable (et sur un distant tu peux faire plusieurs essais successifs).
A mon avis concernant ta requête initiale, ce n'est pas la peine de faire un index commun sur les deux champs surtout qu'ils sont déjà indexés séparément. Au contraire cela devrait ralentir ta requête car le chargement des index prend du temps.

Concernant les index et order by c'est ici

Mais bon pour en avoir le coeur net :
$time = microtime(true);
//exécution requête
$time_end = microtime(true);
$time_tot = $time_end - $time;
echo 'durée exécution  = ' . $time_tot.'<br />';
Puisque ta table est importante tu devrais assez vite voir des différences (en prenant soin toutefois d'utiliser la même variable dans la clause WHERE pour comparer l'efficacité des différentes indexations).

Re: Mettre un index pour un ORDER BY ?

par aqua007 » 22 févr. 2011, 20:34

Dans ma table forum_message id_topic est bien une clé étrangère faisait référence au champs id de ma table forum_topic. Mais nul par dans myslq je l'ai renseigné (je savais pas que c'était possible), c'est pour ça que j'ai mis actuellement id_topic en INDEX avec aussi un INDEX sur le champs date.
Je dispose de topic très lourds (centaines voir milliers de messages par topic parfois).

Merci déjà pour la confirmation de l'utilisation de l'index sur le ORDER BY.

Après je me demandais si en théorie c'était intéressant de mettre un INDEX comprenant 2 champs, sur les champs id_topic + date (en plus du champs index sur id_topic et du champs index sur date qui eux sont utilisés pour d'autres requêtes par exemple) pour ma requête donnée dans mon premier post en particulier (car c'est elle qui est lente parfois), vu qu'elle utilise ces deux champs la.

Ca doit bien servir à quelque chose de pouvoir faire des index sur plusieurs champs à la fois plutot que de faire autant d'index que je champs.