在以下情况下需要有效的查询

时间:2014-08-20 14:34:02

标签: sql oracle oracle10g

有3张桌子

表A

id | value
-----------
   |

表B

id|value|A_id(fk to A)
--------------
  |     |

表C

id|value|B_id(FK to B)|timestamp
--------------------------------
  |     |             |

我编写了一个查询,使用以下查询找出所有最新的不同C值

select A.id, B.id, C.timestamp, C.value
from A,B,C 
where A.id = B.A_id
and B.id = C.B_id
where C.value in (select distinct value from C c2 where c2.value = c.value and c2.value is not null)
and c.timestamp = (select max(timestamp) from C c3 where c3.value = c.value);

除了ID之外,其他列都没有索引。此时此查询需要大约2小时或更长时间才能运行,因为不同C值的数量是221000条记录。有没有一种有效的方法呢?

3 个答案:

答案 0 :(得分:1)

将在主查询中的每一行运行查询内的子查询 在主查询中包含大数据时,这将是一个性能反模式(您有2个子查询)。

您需要一个最大组,可以使用自我左连接来实现。

SELECT A.id a_id, B.id b_id, C1.timestamp, C1.value
From C C1
INNER JOIN B on B.id = C1.b_id
INNER JOIN A on A.id = B.A_id
LEFT JOIN C C2 on C1.value = C2.value 
and 
C1.timstamp < C2.timestamp
WHERE C1.value IS NOT NULL
and C2.id IS NULL

答案 1 :(得分:1)

SELECT distinct A.id, B.id, c.timestamp, c.value FROM 
(
SELECT  c.value,  MAX(c.timestamp) AS max_timestamp FROM c
WHERE NOT c.value IS NULL
GROUP BY  c.value) c1 INNER JOIN c ON c1.value = c.value AND c1.max_timestamp = c.timestamp
    inner join b ON B.id = C.B_id
    inner join a ON A.id = B.A_id

答案 2 :(得分:-2)

尝试其中之一。我想我理解你的联系。希望能帮助到你。第二个查询可能会更快,因为它首先尝试收集最大时间戳,然后加入其他表ID

select A.id, B.id.C.timestamp,c.value
from A 
inner join B on B.B_id = A.id
inner join C on C.C_id = B._B_id
where C.value in (select distinct value from C c2 where c2.value = c.value and c2.value is not null)
and c.timestamp = (select max(timestamp) from C c3 where c3.value = c.value);

WITH

A_ID AS (
SELECT A.id, B.id
from A 
inner join B on B.A_id = A.id
)
, C_ID AS (
SELECT C_ID, value, max(timestamp) 
from C
where value in (select distinct value from C where value is not null)
)
SELECT a.id, a.b_id, c.B_id, c.timestamp, c.value
FROM A_ID a
inner join C_ID c on c.B_ID = a.B_ID
order by a.id