mysqlとORDER BY
組み合わせて使用されるサブクエリ内で句を使用すると、句UNION
が最適化されORDER BY
ます。
これは、デフォルトではa UNION
が順序付けられていないリストを返すため、ORDER BY
は何もしないためです。
最適化はドキュメントで言及されて言っています:
ORDER BYまたはLIMITを個々のSELECTに適用するには、SELECTを囲む括弧内に句を配置します。
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
ただし、個々のSELECTステートメントにORDER BYを使用しても、UNIONはデフォルトで順序付けされていない行のセットを生成するため、最終結果に行が表示される順序については何も意味しません。したがって、このコンテキストでのORDER BYの使用は通常LIMITと組み合わせて使用されるため、SELECTで取得する選択された行のサブセットを決定するために使用されます。最終的なUNIONの結果。SELECTでORDER BYがLIMITなしで表示される場合、それはとにかく効果がないため、最適化されて削除されます。
これの最後の文は効果があるはずなので、少し誤解を招きます。この最適化により、サブクエリ内で順序付けする必要がある状況で問題が発生します。
MySQLにこの最適化を行わせないようにするには、次のようにLIMIT句を追加します。
(SELECT 1 AS rank, id, add_date FROM my_table WHERE distance < 5 ORDER BY add_date LIMIT 9999999999)
UNION ALL
(SELECT 2 AS rank, id, add_date FROM my_table WHERE distance BETWEEN 5 AND 15 ORDER BY rank LIMIT 9999999999)
UNION ALL
(SELECT 3 AS rank, id, add_date from my_table WHERE distance BETWEEN 5 and 15 ORDER BY id LIMIT 9999999999)
高LIMIT
は、OFFSET
ページネーションなどを実行する場合にクエリ全体にを追加できることを意味します。
これにより、ORDER BY
ユニオンごとに異なる列を使用できるという追加の利点も得られます。