0

我有这个查询需要大约 5 分钟才能返回一个结果集,但我想不出更好的方法来做到这一点。有问题的表始终有大约 15 或 2000 万行,其架构可以总结为

create table conversation(
  id raw, -- GUID
  vendor varchar,
  snumber number
  rcvdate date
)

在我们存储从供应商发送或发送给供应商的消息的地方,每条消息都有一个由所有对话(相关消息集)共享的序列号。问题出现是因为供应商可以有父代,而消息可以有父代的代码(我们可以假设在查询时我们知道供应商的代码及其父代的代码)。假设 A 和 B 是 2 个具有共同父 P 的供应商,表格可能看起来像

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

这两个子查询正在扼杀性能。对话表在本示例中包含的所有列中都有索引。我认为必须是一种巧妙的方式来对这些信息进行分组,而不必使用临时表或子查询,但我想不出一个。任何帮助将不胜感激。

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

IE

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

表示如果那个号码中有一个“A”供应商,那么你想为“P”arent 供应商返回它,否则没有。

于 2012-12-09T21:05:26.640 回答