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列添加索引。