Optimisation des sous-requêtes
<<<
Se passer des sous-requêtes avec les premières versions de MySQL Manipulation de données : SELECT , INSERT , UPDATE , DELETE
>>>

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.11 Se passer des sous-requêtes avec les premières versions de MySQL

Jusqu'à la version 4.0 inclue, seules les requêtes imbriquées de la forme INSERT ... SELECT ... et REPLACE ... SELECT ... étaient supportées. La clause IN() peut être utilisée dans certains contextes.

Il est souvent possible de réécrire une requête sans sous-requête :

SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
Cela peut se réécrire :

SELECT t1.* FROM t1,t2 WHERE t1.id=t2.id;
Les requêtes :

SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2);
SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
peuvent être réécrites :

SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id
                                       WHERE table2.id IS NULL;
Une clause LEFT [OUTER] JOIN peut être plus rapide qu'une sous-requête équivalent, car le serveur va pouvoir l'optimiser bien mieux : c'est un fait qui n'est pas spécifique à MySQL. Avant SQL-92, les jointures externes n'existaient pas, et les sous-requêtes étaient la seule méthode pour résoudre certains problèmes. Aujourd'hui, le serveur MySQL et d'autres bases de données modernes offrent toute une gamme de jointures externes.Pour les sous-requêtes plus complexes, vous pouvez simplement créer des tables temporaires pour contenir les résultats intermédiaires. Dans certains cas, cela ne sera pas possible. C'est notamment le cas des commandes de type DELETE, pour lesquelles le standard SQL ne supporte pas les jointures, sauf pour les sous-requêtes. Dans ces situations, trois solutions s'offrent à vous :
  • Passez en MySQL version 4.1.
  • Utilisez un langage de programmation procédural, comme Perl ou PHP, pour envoyer la requête SELECT , lire les clés primaires à effacer, et utiliser ces valeurs pour soumettre des requêtes de type DELETE ( DELETE FROM ... WHERE ... IN (key1, key2, ...) ).
  • La troisième option est d'utiliser le client interactif de mysql pour construire et exécuter une liste de commande DELETE automatiquement, avec la fonction CONCAT() au lieu de l'opérateur || . Par exemple :
    
    SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', "'", tab1.pkid, "'", ';')
      FROM tab1, tab2
    WHERE tab1.col1 = tab2.col2;
    Vous pouvez placer cette requête dans un fichier de script, et rediriger son résultat vers le client en ligne de commande mysql , pour que ce dernier lance une seconde instance de l'interprêteur :
    
    shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb
    
MySQL 4.0 supporte les commandes DELETE multi-tables qui peuvent être utilisées pour effacer des lignes dans une table en fonction d'informations qui sont dans une autre table, ou même effacer des lignes simultanément dans plusieurs tables. Les commandes UPDATE multi-tables sont aussi supportés depuis la version 4.0.

<< Se passer des sous-requêtes avec les premières versions de MySQL >>
Optimisation des sous-requêtes Sous-sélections ( SubSELECT ) Manipulation de données : SELECT , INSERT , UPDATE , DELETE