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 siFULLTEXT
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 voirSHOW 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