同じレイアウトの複数のテーブルで構成されるロギングシステムをセットアップしただけです。
データソースごとに1つのテーブルがあります。
ログビューアについて、私はしたいです
すべてのテーブルには、インデックス付きの日付/時刻列であるzeitpunkt
というフィールドが含まれています。
私の最初の試みは:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730)
ORDER BY zeit DESC LIMIT 10;
両方のテーブルのすべての行がサブクエリによって返され、UNION
の後にソートされるため、オプティマイザはここでインデックスを使用できません。
私の回避策は次のとおりです:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
ORDER BY zeit DESC LIMIT 10;
両方のサブクエリはUNION
の前にソートおよび制限されている必要があるため、クエリエンジンがここでインデックスを使用すると予想していました。
私は本当にこれだと思っていましたが、クエリでEXPLAIN
を実行すると、サブクエリがまだ両方のテーブルを検索していることがわかります。
EXPLAINing
サブクエリ自体は目的の最適化を示していますが、UNIONing
それらを一緒にすると、そうではありません。
私は何か見落としてますか?
UNION
サブクエリ内のORDER BY
句はLIMIT
がないと無視されることを知っていますが、制限があります。
編集:
実際には、account_id
条件のないクエリもおそらく存在します。
テーブルはすでに存在し、データが入力されています。ソースによってはレイアウトが変わる場合があるので分割していきたい。さらに、ログクライアントは、理由により異なる資格情報を使用します。
ログリーダーと実際のテーブルの間に一種のレイヤーを維持する必要があります。
以下は、クエリ全体と最初のサブクエリの実行プラン、およびテーブルレイアウトの詳細です。
好奇心から、このバージョンを試すことができますか?サブクエリが個別に使用するのと同じインデックスを使用するようにオプティマイザをだましてしまう可能性があります。
SELECT *
FROM
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
AS a
UNION ALL
SELECT *
FROM
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
AS b
ORDER BY zeit DESC LIMIT 10;
私はまだあなたが持つことができる最高のインデックスは複合物だと思います(account_id, zeitpunkt)
。それは10行を高速に生成し、トリックは必要ありません。