Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MYSQL - Erstellen Sie eine einzelne SQL-Abfrage aus mehreren Abfragen

Technik 1:Kombinieren von Skalaren:

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

-->

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

Wenn a ist so etwas wie COUNT(*) , dann wissen Sie, dass es genau ein Ergebnis geben wird; daher das LIMIT 1 ist unnötig.

Wenn eine dieser Unterabfragen möglicherweise keine Zeilen zurückgibt, erhalten Sie NULL .

Technik 2:Ein select kann fast überall verwendet werden, wo ein Ausdruck verwendet werden kann. Das Obige ist technisch gesehen ein Beispiel dafür. Auch...

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

Auch hier muss die Unterabfrage eine einzelne Zeile zurückgeben, um dies zu ermöglichen.

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

Das wird ungefähr so, nachdem die Unterabfrage ausgewertet wurde:

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

(Es ist nicht effizient, aber es funktioniert.)

Diese 3 sind ähnlich, aber nicht unbedingt effizient:

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

Dies ist ähnlich, findet aber die übereinstimmenden Elemente, die fehlen von B:

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

UNION sollte für Abfragen mit ähnlicher Ausgabe verwendet werden:

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

Das erzeugt eine beliebige Anzahl von Zeilen von A und eine beliebige Anzahl von Zeilen von B. Duplikate werden entfernt, wenn Sie UNION DISTINCT verwenden , oder beibehalten, wenn Sie UNION ALL verwenden .

ORDER BY ... LIMIT ... wird knifflig. OFFSET wird noch kniffliger.

Leistung

  • Vermeiden Sie IN ( SELECT ...) es ist normalerweise das langsamere der drei.
  • Vermeiden Sie führende Platzhalter in LIKE; siehe ob FULLTEXT wäre eine bessere Option.
  • INDEX(path) , INDEX(parent_id, child_id) ("Bedeckung"), INDEX(scope, path, scope_id); vielleicht andere, aber ich muss SHOW CREATE TABLE sehen .
  • EAV-Schema vermeiden; das ist schlecht für die leistung. Ich habe einen Link hinzugefügt; siehe die vielen anderen Diskussionen. Außerdem:http://mysql.rjweb.org/doc.php/eav und http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta

Diese Gegenstände sind wahrscheinlich wichtiger (für die Leistung) als die Kombination der Anweisungen. Siehe https://meta.stackexchange.com/questions/ 66377/was-ist-das-xy-problem