0

結果セットを返すのに約 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 テーブルには、この例に含めたすべての列にインデックスがあります。一時テーブルやサブクエリを使用せずにこの情報をグループ化するための賢い方法である必要があると考えていますが、思いつきません。どんな助けでも大歓迎です。

4

1 に答える 1

0

次のようなものが欲しいようです:

SQL> select vendor, snumber, rcvdate
  2    from (select vendor, snumber, rcvdate,
  3                 max(case when vendor = 'A' then 'Y' end) over (partition by snumber) has_vendor
  4            from conversation
  5           where vendor in ( 'A', 'P' )
  6           order by rcvdate desc)
  7   where has_vendor = 'Y'
  8     and rownum <= 100
  9   order by rcvdate;

V    SNUMBER RCVDATE
- ---------- --------------------
A          1 01-jan-2012 00:00:00
P          1 02-jan-2012 00:00:00
A          1 02-jan-2012 00:00:00
P          2 03-jan-2012 00:00:00
A          2 03-jan-2012 00:00:00
A          2 04-jan-2012 00:00:00

すなわち

max(case when vendor = 'A' then 'Y' end) over (partition by snumber) has_vendor

その snumber に「A」ベンダーがある場合は、それを「P」arent ベンダーに返したいと言い、それ以外の場合はそうではありません。

于 2012-12-09T21:05:26.640 に答える