テクニック1:スカラーを組み合わせる:
SELECT a ... LIMIT 1;
SELECT b ... LIMIT 1;
-->
SELECT
( SELECT a ... LIMIT 1) AS a,
( SELECT b ... LIMIT 1) AS b ;
a
の場合 COUNT(*)
のようなものです 、次に、結果が1つだけになることがわかります。したがって、 LIMIT 1
不要です。
これらのサブクエリの1つが行を返さない可能性がある場合は、 NULL
を取得します。 。
テクニック2:selectは、式を使用できるほとんどすべての場所で使用できます。上記は、技術的にはその一例です。また...
SELECT ... WHERE x = ( SELECT ... ) ...
繰り返しますが、サブクエリはそれを可能にするために単一の行を返す必要があります。
SELECT ...
WHERE x LIKE CONCAT('%', ( SELECT ... ), '%')
...;
サブクエリが評価されると、次のようになります。
SELECT
WHERE x LIKE '%foo%'
...;
(効率的ではありませんが、機能します。)
これら3つは似ていますが、必ずしも互いに効率的であるとは限りません。
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
これは似ていますが、欠落している一致するアイテムを見つけます Bから:
SELECT ... FROM A LEFT JOIN B ON B.x = A.x
WHERE B.id IS NULL
UNION
同様の出力を持つクエリに使用する必要があります:
SELECT x,y FROM A
UNION
SELECT x,y FROM B
これにより、Aから任意の数の行が生成され、Bから任意の数の行が生成されます。 UNIONDISTINCT
を使用すると、重複が削除されます。 、または UNION ALL
を使用する場合は保持されます 。
ORDER BY ... LIMIT ...
トリッキーになります。 オフセットコード> さらにトリッキーになります。
パフォーマンス
-
IN(SELECT ...)
は避けてください 通常、3つのうち遅い方です。 -
LIKE
で先頭のワイルドカードを使用しないでください;FULLTEXT
かどうかを確認します より良いオプションです。 -
INDEX(path)
、INDEX(parent_id、child_id)
("covering")、INDEX(scope、path、scope_id)
;他の人かもしれませんが、SHOW CREATE TABLE
を見る必要があります 。 - EAVスキーマは避けてください。パフォーマンスに悪影響を及ぼします。リンクを追加しました。他の多くの議論を参照してください。また: http://mysql.rjweb.org/doc.php/eav
および
http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta
それらのアイテムはおそらく ステートメントを組み合わせるよりも(パフォーマンスにとって)重要です。 https://meta.stackexchange.com/questions/を参照してください66377 / what-is-the-xy-problem