次の 2 つの SQL ステートメントは、常に同じ結果セットを生成しますか?
1. SELECT * FROM MyTable where Status='0' order by StartTime asc limit 10
2. SELECT * FROM (SELECT * FROM MyTable where Status='0' order by StartTime asc) limit 10
はい。ただし、サブクエリの順序付けは、おそらく悪い習慣です。ORDER BY
2番目の例では、サブクエリの外側にさらに追加することができます。
SELECT *
FROM (SELECT *
FROM Test
ORDER BY ID ASC
) AS A
ORDER BY ID DESC
LIMIT 10;
SQLite はORDER BY
、外側のクエリでそれらを再度ソートする前に、内側のクエリで引き続き実行します。無駄な資源の浪費。
それぞれの実行計画を表示できるように、SQL Fiddleを実行してデモンストレーションを行いました。
いいえ。まず、StartTime
列にUNIQUE
制約がない可能性があるためです。したがって、最初のクエリでさえ、常に同じ結果を生成するとは限りません。
次に、StartTime が同じ行が 2 つ存在しない場合でも、答えは依然として負です。
最初のステートメントは常に順序付けられStartTime
、最初の 10 行が生成されます。ORDER BY
2 番目のクエリは同じ結果セットを生成する可能性がありますが、サブクエリ内の が冗長であることを理解していないプリミティブ オプティマイザーを使用している場合に限られます。実行計画にこの順序付けフェーズが含まれている場合のみ。
SQLite クエリ オプティマイザーは (現時点では) あまり明るくないかもしれませんが、それを実行するだけです (実際にはわかりません。SQLite* のソース コードを確認する必要があります)。そのため、2 つのクエリが常に同じ結果を生成しているように見える場合があります。それでも、それを当てにするのは得策ではありません。SQLite の将来のバージョンでどのような変更が行われるかはわかりません。
どのDBMSでも、LIMIT
なしで使用するのは良い習慣ではないと思います。ORDER BY
今は機能するかもしれませんが、これらのクエリがアプリケーションによってどれくらい使用されるかはわかりません。また、SQLite がアップグレードされたり、DBMS が変更されたりしたときに、あなたがいない可能性があります。
(*) @Gareth のリンクは、現在の SQLite コードが冗長な順序付けを実行するのに十分愚かであることを示唆する実行計画を提供します。