Sql 从另一个表多行更新表
我的上下文是Sql 从另一个表多行更新表,sql,postgresql,multiple-records,Sql,Postgresql,Multiple Records,我的上下文是PostgreSQL 8.3 我需要加快查询速度,因为两个表都有数百万条记录 对于表调用中的每一行,Trunks表中有两行。对于每个call\u id,当trunk\u id是两行中的最低trunk\u id时,我希望将值从trunks.trunk复制到calls.orig\u trunk。。。当trunk_id是两行中的最高trunk_id时,将trunks.trunk中的值复制到calls.orig_trunk 表调用的初始内容: Call_ID | dialed_number
PostgreSQL 8.3
我需要加快查询速度,因为两个表都有数百万条记录
对于表调用中的每一行,Trunks表中有两行。对于每个call\u id,当trunk\u id是两行中的最低trunk\u id时,我希望将值从trunks.trunk复制到calls.orig\u trunk。。。当trunk_id是两行中的最高trunk_id时,将trunks.trunk中的值复制到calls.orig_trunk
表调用的初始内容:
Call_ID | dialed_number | orig_trunk | dest_trunk
--------|---------------|------------|-----------
1 | 5145551212 | null | null
2 | 8883331212 | null | null
3 | 4164541212 | null | null
Call_ID | dialed_number | orig_trunk| dest_trunk
--------|---------------|-----------|----------
1 | 5145551212 | 116 | 9
2 | 8883331212 | 168 | 3
3 | 4164541212 | 124 | 9
桌尾箱:
Call_ID | trunk_id | trunk
--------|----------|-------
1 | 1 | 116
1 | 2 | 9
2 | 3 | 168
2 | 4 | 3
3 | 5 | 124
3 | 6 | 9
表调用的最终内容:
Call_ID | dialed_number | orig_trunk | dest_trunk
--------|---------------|------------|-----------
1 | 5145551212 | null | null
2 | 8883331212 | null | null
3 | 4164541212 | null | null
Call_ID | dialed_number | orig_trunk| dest_trunk
--------|---------------|-----------|----------
1 | 5145551212 | 116 | 9
2 | 8883331212 | 168 | 3
3 | 4164541212 | 124 | 9
我已经为每一列创建了索引
update calls set orig_trunk = t2.trunk
from ( select call_id,trunk_id from trunks
order by trunk_id ASC ) as t2
where (calls.call_id=t2.call_id );
update calls set dest_trunk = t2.trunk
from ( select call_id,trunk_id from trunks
order by trunk_id DESC ) as t2
where (calls.call_id=t2.call_id );
有什么想法吗?从发布的示例来看,似乎正在执行许多不必要的更新。下面是一个查询示例,用于获取您要查找的结果:
select distinct c.call_id, c.dialed_number
,first_value(t.trunk) over w as orig_trunk
,last_value(t.trunk) over w as dest_trunk
from calls c
join trunks t on (t.call_id = c.call_id)
window w as (partition by c.call_id
order by trunk_id
range between unbounded preceding
and unbounded following
)
在不使用分析函数的情况下,还有其他方法可以执行此操作,例如:
select x.call_id
,x.dialed_number
,t1.trunk as orig_trunk
,t2.trunk as dest_trunk
from (select c.call_id, c.dialed_number
,min(t.trunk_id) as orig_trunk_id
,max(t.trunk_id) as dest_trunk_id
from calls c
join trunks t on (t.call_id = c.call_id)
group by c.call_id, c.dialed_number
) x
join trunks t1 on (t1.trunk_id = x.orig_trunk_id)
join trunks t2 on (t2.trunk_id = x.dest_trunk_id)
试着看看什么在你的情况下最有效。可能希望在连接列上建立索引
如何处理结果集取决于应用程序的性质。这是一次性的吗?那么为什么不从结果集中创建一个新表呢
CREATE TABLE trunk_summary AS
SELECT ...
它是不断变化的吗?它经常被访问吗?仅仅创建一个视图就足够了吗?或者根据结果集执行更新。也许可以一次更新一个范围。这要看情况而定,但这可能是一个开始。这是最后一段代码,测试条件作为注释。 子查询非常高效和快速。然而,测试表明,对表进行分区比对子查询的效率对执行时间的影响更大。在一个有一百万行的表上,更新需要80秒。在一个1200万行的表上,更新需要580秒
update calls1900 set orig_trunk = a.orig_trunk, dest_trunk = a.dest_trunk
from (select
x.call_id,
t1.trunk as orig_trunk, t2.trunk as dest_trunk
from (select calls1900.call_id
,min(t.trunk_id) as orig_trunk_id
,max(t.trunk_id) as dest_trunk_id
from calls1900
join trunks t on (t.call_id = calls1900.call_id)
-- where calls1900.call_id between 43798930 and 43798950
group by calls1900.call_id
) x
join trunks t1 on (t1.trunk_id = x.orig_trunk_id)
join trunks t2 on (t2.trunk_id = x.dest_trunk_id)
) a
where (calls1900.call_id = a.call_id); -- and (calls1900.call_id between 43798930 and 43798950)<code>
如果您向我们提供一个sql FIDLE数据示例。它使人们更容易尝试一些东西,并将其与执行情况进行比较。另外一种加速过程的方法是,如果您还没有这样做,则向id列添加索引。