Mysql
 sql >> Base de données >  >> RDS >> Mysql

MYSQL - Créer une requête SQL unique à partir de plusieurs requêtes

Technique 1 : Combiner les scalaires :

SELECT a ... LIMIT 1;
SELECT b ... LIMIT 1;

-->

SELECT
    ( SELECT a ... LIMIT 1) AS a,
    ( SELECT b ... LIMIT 1) AS b ;

Si a est quelque chose comme COUNT(*) , alors vous savez qu'il y aura exactement un résultat ; d'où la LIMIT 1 est inutile.

Si l'une de ces sous-requêtes risque de ne renvoyer aucune ligne, vous obtenez alors NULL .

Technique 2 :Une sélection peut être utilisée presque partout où une expression peut être utilisée. Ce qui précède en est, techniquement, un exemple. Aussi...

SELECT ... WHERE x = ( SELECT ... ) ...

Encore une fois, la sous-requête doit renvoyer une seule ligne pour rendre cela possible.

SELECT ...
    WHERE x LIKE CONCAT('%', ( SELECT ... ), '%')
    ...;

Cela devient quelque chose comme ceci après l'évaluation de la sous-requête :

SELECT
    WHERE x LIKE '%foo%'
    ...;

(Ce n'est pas efficace, mais ça marche.)

Ces 3 sont similaires, mais pas forcément efficaces les uns que les autres :

SELECT ...
    WHERE x IN ( SELECT ... )

SELECT ... FROM A
    WHERE EXISTS( SELECT ... FROM B
                  WHERE B.x = A.x )

SELECT ... FROM A JOIN B ON B.x = A.x

Ceci est similaire mais trouve les éléments correspondants qui sont manquants de B :

SELECT ... FROM A LEFT JOIN B ON B.x = A.x
    WHERE B.id IS NULL
    

UNION doit être utilisé pour les requêtes qui ont un résultat similaire :

SELECT x,y FROM A
UNION
SELECT x,y FROM B

Cela produira n'importe quel nombre de lignes à partir de A et n'importe quel nombre de lignes à partir de B. Les doublons sont supprimés si vous utilisez UNION DISTINCT , ou conservé si vous utilisez UNION ALL .

ORDER BY ... LIMIT ... devient délicat. OFFSET devient encore plus délicat.

Performances

  • Éviter IN ( SELECT ...) c'est généralement le plus lent des trois.
  • Évitez les caractères génériques de début dans LIKE; voir si FULLTEXT serait une meilleure option.
  • INDEX(path) , INDEX(parent_id, child_id) ("couvrant"), INDEX(scope, path, scope_id); peut-être d'autres, mais j'ai besoin de voir SHOW CREATE TABLE .
  • Évitez le schéma EAV ; c'est mauvais pour les performances. j'ai ajouté un lien; voir les nombreuses autres discussions. Aussi :http://mysql.rjweb.org/doc.php/eav et http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta

Ces éléments sont probablement plus important (pour la performance) que de combiner les instructions ensemble. Voir https://meta.stackexchange.com/questions/ 66377/quel-est-le-problème-xy