Erreurs de sous-requêtes
<<<
Optimisation des sous-requêtes Se passer des sous-requêtes avec les premières versions de MySQL
>>>

14.1.8 Sous-sélections ( SubSELECT )
14.1 Manipulation de données : SELECT , INSERT , UPDATE , DELETE
14 Syntaxe des commandes SQL
 Manuel de Référence MySQL 4.1 : Version Française

Les sous-requêtes comme opérateur scalaire
Comparaisons avec les sous-requêtes
Sous-requêtes avec les clauses ANY , IN et SOME
Sous-requêtes avec ALL
Sous-requêtes corrélées
EXISTS et NOT EXISTS
Sous-requêtes de ligne
Sous-requêtes dans la clause FROM
Erreurs de sous-requêtes
->Optimisation des sous-requêtes
Se passer des sous-requêtes avec les premières versions de MySQL

14.1.8.10 Optimisation des sous-requêtes

Le développement des sous-requêtes se poursuit, et aucun des conseils d'optimisation ne sera valable longtemps. Voici quelques astuces que vous voulez prendre en compte :

  • Utiliser une clause de sous-requête pour affecter le nombre ou l'ordre des lignes dans une sous-requête, par exemple :
    
    SELECT * FROM t1 WHERE t1.column1 IN
      (SELECT column1 FROM t2 ORDER BY column1);
    SELECT * FROM t1 WHERE t1.column1 IN
      (SELECT DISTINCT column1 FROM t2);
    SELECT * FROM t1 WHERE EXISTS
      (SELECT * FROM t2 LIMIT 1);
  • Remplacer une jointure par une sous-requête. Par exemple :
    
    SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN (
      SELECT column1 FROM t2);
    au lieu de
    
    SELECT DISTINCT t1.column1 FROM t1, t2
      WHERE t1.column1 = t2.column1;
  • Déplacer une clause FROM externe dans une sous-requête, comme ceci :
    
    SELECT * FROM t1
      WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
    au lieu de
    
    SELECT * FROM t1
      WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
    Un autre exemple :
    
    SELECT (SELECT column1 + 5 FROM t1) FROM t2;
    
    au lieu de
    
    SELECT (SELECT column1 FROM t1) + 5 FROM t2;
    
  • Utiliser une sous-requête de ligne plutôt qu'une corrélation. Par exemple :
    
    SELECT * FROM t1
      WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
    au lieu de
    
    SELECT * FROM t1
      WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1
      AND t2.column2=t1.column2);
  • Utiliser NOT (a = ANY (...)) au lieu de a <> ALL (...) .
  • Utiliser x = ANY (table containing {1,2}) plutôt que x=1 OR x=2 .
  • Utiliser = ANY de préférence à EXISTS
Le truc ci-dessus peut accélérer certains programmes, et en ralentir d'autres. En utilisant la fonction utilitaire BENCHMARK() , vous pouvez obtenir une idée de votre cas. Ne vous attardez pas trop à transformer vos jointures, sauf si la compatibilité avec les anciennes versions est importante pour vous.

Quelques optimisation que MySQL va prendre en charge lui-même :

  • MySQL va exécuter les sous-requêtes non corrélées une seule fois (utilisez la commande EXPLAIN pour vous assurer que les requêtes ne sont pas correllées).
  • MySQL va transformer les sous-requêtes IN / ALL / ANY / SOME pour essayer de profiter de la possibilité que les colonnes sélectionnées dans la sous-requêtes sont indexées.
  • MySQL remplacera les sous-requêtes de la forme
    
    ... IN (SELECT indexed_column FROM single_table ...)
    
    par une recherche dans un index, que EXPLAIN décrira comme une jointure de type spécial.
  • MySQL va améliorer les expressions de la forme
    
    valeur {ALL|ANY|SOME} {> | < | >= | <=} (sous-requête non-correllée)
    
    avec une expression impliquant MIN ou MAX (à moins d'une valeur NULL ou d'ensembles SET vides). Par exemple,
    
    WHERE 5 > ALL (SELECT x FROM t)
    
    revient à
    
    WHERE 5 > (SELECT MAX(x) FROM t)
    
Il y a un chapitre intitulé ``Comment MySQL adapte les sous-requêtes'' dans les manuels internes de MySQL, que vous pouvez trouver en téléchargeant les sources de MySQL : il est dans un fichier appelé internals.texi , dans le dossier Docs .

<< Optimisation des sous-requêtes >>
Erreurs de sous-requêtes Sous-sélections ( SubSELECT ) Se passer des sous-requêtes avec les premières versions de MySQL