table1 と table2 の両方に多数の行 (つまり、数十万行) があると仮定すると、次のクエリは非効率的ですか?
編集:フィールドによる並べ替えが追加されました。
SELECT * FROM (
SELECT title, updated FROM table1
UNION
SELECT title, updated FROM table2
) AS query
ORDER BY updated DESC
LIMIT 25
table1 と table2 の両方に多数の行 (つまり、数十万行) があると仮定すると、次のクエリは非効率的ですか?
編集:フィールドによる並べ替えが追加されました。
SELECT * FROM (
SELECT title, updated FROM table1
UNION
SELECT title, updated FROM table2
) AS query
ORDER BY updated DESC
LIMIT 25
これはさらに高速になるはずですが、ORDER BY が表示されないので、実際に必要な 25 レコードは何ですか?
SELECT * FROM (
SELECT title FROM table1 LIMIT 25
UNION
SELECT title FROM table2 LIMIT 25
) AS query
LIMIT 25
明確な結果がどうしても必要な場合は、代わりにunion all
andgroup by
節を使用することもできます。
SELECT title FROM (
SELECT title FROM table1 group by title
UNION ALL
SELECT title FROM table2 group by title
) AS query
group by title
LIMIT 25;
limit
テスト データベース (at) でそれぞれ ~920K 行の 2 つのテーブルのインデックス付き ID 列で句なしでこれをテスト$work
すると、上記のクエリで 1 秒を少し超え、union
.
はい、内部クエリで order by と limit を使用します。
SELECT * FROM (
(SELECT title FROM table1 ORDER BY title ASC LIMIT C)
UNION
(SELECT title FROM table2 ORDER BY title ASC LIMIT C)
) AS query
LIMIT 25
これは、N (数十万) ではなく C 行のみを通過します。ORDER BY は必須であり、インデックス付きの列にある必要があります。
C は、ドメインに従って調整する必要がある発見的定数です。重複が少ないと予想される場合は、おそらく C=50-100 で問題ありません。
EXPLAIN を使用して、これを自分で調べることもできます。
UNION
distinct
レコードをフェッチするために追加のパスを作成する必要があるため、を使用する必要がありますUNION ALL
。