結果セットを返すのに約 5 分かかるこのクエリがあり、それを行うためのより良い方法がわかりません。問題のテーブルには常に約 1,500 万または 2,000 万行あり、そのスキーマは次のように要約できます。
create table conversation(
id raw, -- GUID
vendor varchar,
snumber number
rcvdate date
)
ベンダーから、またはベンダーに送信されたメッセージを保存する場合、各メッセージには、すべての会話 (関連するメッセージのセット) で共有されるシーケンス番号があります。問題が発生するのは、ベンダーが親を持つことができ、メッセージが親のコードを持つことができるためです (クエリ時にベンダーのコードとその親のコードの両方を知っていると仮定できます)。A と B が共通の親 P を持つ 2 つのベンダーであると仮定すると、表は次のようになります。
Vendor snumber date
------------------------------
A 1 01-JAN-2012
P 1 02-JAN-2012
A 1 02-JAN-2012
A 2 03-JAN-2012
P 2 03-JAN-2012
B 3 03-JAN-2012
P 3 04-JAN-2012
A 2 04-JAN-2012
A との間の最後の N メッセージを照会し、vendor=A または (vendor=P と vendor=A と同じ snumber の別のレコード) のメッセージを取得する必要があります。つまり、次のようになります。
Vendor snumber date
------------------------------
A 1 01-JAN-2012
P 1 02-JAN-2012
A 1 02-JAN-2012
A 2 03-JAN-2012
P 2 03-JAN-2012
A 2 04-JAN-2012
私がしたことは、A との間の会話を一時テーブル T(id, snumber) に格納してから返すことでした
select * from (
select * from conversations c
where
exists (select id from T where T.id = C.id) or
( c.vendor=l_parent and exists (select snumber from T where T.snumber=c.snumber )
) where rownum <= l_N
これらの 2 つのサブクエリがパフォーマンスを低下させています。conversations テーブルには、この例に含めたすべての列にインデックスがあります。一時テーブルやサブクエリを使用せずにこの情報をグループ化するための賢い方法である必要があると考えていますが、思いつきません。どんな助けでも大歓迎です。