每个月我在oracle数据库上做一个简单的更新语句。但是,从星期一开始需要很长时间。该表每个月增长5%。现在有800万条记录被存储。简单的Oracle UPDATE语句异常糟糕的性能
陈述:
update /*+ parallel(destination_tab, 4) */ destination_tab dest
set (full_name, state) =
(select /*+ parallel(source_tab, 4) */ dest.name, src.state
from source_tab src
where src.city = dest.city);
在实际有20个领域的更新,而不是只有两个......但这样看起来更容易descripe问题。
解释计划:
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------
| 0 | update statement | | 8517K| 3167M| 579M (50)|999:59:59 |
| 1 | update | destination_tab | | | | |
| 2 | PX COORDINATOR | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10000 | 8517K| 3167M| 6198 (1)| 00:01:27 |
| 4 | px block iterator | | 8517K| 3167M| 6198 (1)| 00:01:27 |
| 5 | table access full | DESTINATION_TAB | 8517K| 3167M| 6198 (1)| 00:01:27 |
| 6 | table access by index rowid| SOURCE_TAB | 1 | 56 | 1 (0)| 00:00:01 |
|* 7 | index unique scan | CITY_PK | 1 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
谁能descripe给我,这怎么可能呢?该计划看起来非常糟糕!非常非常感谢你。
你为什么要这样做?每个月你更新你的800万行中的每一行?这永远不会很快,而且肯定是不必要的。一旦你更新了行,是否真的需要每个月再次更新一次?如果您希望所有行都具有最新的源信息,那么为什么不要在source_tab(join)中选择它,以查看它并且根本不将它复制到destination_tab? – 2013-03-17 16:42:27
当你说这个计划“看起来很糟糕”时,我猜你的意思是DESTINATION_TAB上的全表访问?错,那很好! – 2013-03-17 16:43:10
源表中有多少行(大约)? (有统计信息吗?) – Mat 2013-03-17 16:43:21