履歴データを含む複数のテーブルがあるため、id 間に 1 対 1 の関係はありません。
ID と、データがアクティブになったことを示すタイムスタンプに参加する必要があります。データがまだアクティブである場合、または古いデータに設定されていない場合、TO_TIMESTMP は null になる可能性があります。
いくつかのグループ化後の私のメインテーブルは、次のようなものを出力します:
TABLE_A
AID USER_ID AMOUNT FROM_TIMESTMP TO_TIMESTMP
1 1 2 11/21/2012 00:00:00 12/04/2012 11:59:00
1 2 3 11/24/2012 12:00:00 null
2 1 2 11/21/2012 01:00:00 null
次に、さらにリンクするために使用する別のテーブルがあります
TABLE_B
AID CID FROM_TIMESTMP TO_TIMESTMP HIST_ID
1 3 11/01/2012 00:00:00 null 1
1 3 11/21/2012 00:00:00 12/04/2012 11:59:00 2
1 3 11/24/2012 12:00:00 null 3
2 4 11/21/2012 00:59:59 null 4
私の3番目のテーブルは次のようになります。
TABLE_C
CID VALUE FROM_TIMESTMP TO_TIMESTMP HIST_ID
3 A 11/01/2012 00:00:00 null 1
3 B 11/21/2012 00:00:00 11/24/2012 11:59:00 2
3 C 11/24/2012 12:00:00 null 3
4 D 11/21/2012 01:00:01 null 4
テーブル A をテーブル C からテーブル B までの値と組み合わせたい場合の期待される出力は次のとおりです。
AID USER_ID AMOUNT FROM_TIMESTMP TO_TIMESTMP VALUE
1 1 2 11/21/2012 00:00:00 12/04/2012 11:59:00 B
1 2 3 11/24/2012 12:00:00 null C
2 1 2 11/21/2012 01:00:00 null D
テーブル A の AMOUNT とテーブル C の VALUE を除くすべてにインデックスがあり、次の SQL を使用してデータを引き出します。
SELECT a.AID, a.USER_ID, a.AMOUNT, a.FROM_TIMESTMP, a.TO_TIMESTMP, c.VALUE from
(SELECT AID, USER_ID, SUM(AMOUNT), FROM_TIMESTMP, TO_TIMESTMP from TABLE_A GROUP BY AID, USER_ID, FROM_TIMESTMP, TO_TIMESTMP) a
inner join TABLE_B b on b.HIST_ID in (select max(HIST_ID) from TABLE_B
where AID = a.AID and FROM_TIMESTMP <= a.FROM_TIMESTMP+1/2880 and (TO_TIMESTMP>= a.FROM_TIMESTMP or TO_TIMESTMP is null))
inner join TABLE_C c on c.HIST_ID in (select max(HIST_ID) from TABLE_C
where CID = b.CID and FROM_TIMESTMP <= a.FROM_TIMESTMP+1/2880 and (TO_TIMESTMP>= a.FROM_TIMESTMP or TO_TIMESTMP is null));
データが保存されるタイミングに矛盾があるため、開始タイムスタンプがほぼ同時に作成された場合に備えて、開始タイムスタンプを比較するときに 30 秒の猶予期間を追加しました。これを改善する方法はありますか?
MAX(HIST_ID) のものを選択するので、TABLE_A の AID=1 や USER_ID=2 のようなケースは、他のテーブルからの id/timestamp に一致する最新の行のみを取得します。
私の実際のデータでは、このように 4 つのテーブル (2 つだけではなく) をインナー ジョインし、ローカル テスト データでうまく機能します (すべてのデータを要求するときに、11 秒で 42000 行をわずかに超えます)。
しかし、データ量が本番に近いテスト環境で実行しようとすると、FROM_TIMESTMP を 2 つの日付の間に設定することで、最初のテーブルでクエリする行の量を約 6000 行に制限しても、実行が遅くなります。
別の方法でテーブルの結合のパフォーマンスを向上させる方法はありますか?