Sql Oracle 11g更新具有数百万条记录的表中的行

Sql Oracle 11g更新具有数百万条记录的表中的行,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我正在处理一个表,它有许多字段和1亿个数据,并且在一些字段上有一个复合键。样本表emp,数百万行中只有几行,如下所示: +------+------+------+------+ | Col1 | Col2 | Col3 | Col4 | +------+------+------+------+ | 11 | 21 | 31 | X | | 12 | 22 | 32 | X | | 14 | 24 | 34 | X | | 11 |

我正在处理一个表,它有许多字段和1亿个数据,并且在一些字段上有一个复合键。样本表emp,数百万行中只有几行,如下所示:

+------+------+------+------+
| Col1 | Col2 | Col3 | Col4 |
+------+------+------+------+
|   11 |   21 |   31 | X    |
|   12 |   22 |   32 | X    |
|   14 |   24 |   34 | X    |
|   11 |   21 |   31 | 555  |
|   11 |   21 |   31 | 551  |
|   12 |   22 |   32 | 89   |
|   14 |   24 |   34 | 45   |
+------+------+------+------+
假设组合键在
Col1
Col4
之间。假设Col1、Col2、Col3一起表示一个组Id。第一行的
Col4
X
,因此我需要从
Col1=11
Col2=21
Col3=31
的表中选择所有记录。接下来,因为第二行是12,22,32,'X',我需要选择所有带有
Col1=11
Col2=22
Col3=32
的行。对于
Col4=X
的所有情况,依此类推

我尝试使用带有游标的for循环,但由于表中有1亿个数据和复合键,因此这需要花费大量时间。这需要很长时间

我尝试的循环语句的伪代码:

result= select Col1,Col2,Col3 from emp where `Col4=X`.
for each row in result
do
   finalresult += select * from table where Col1 = row.Col1 and Col2 = row.Col2 and Col3 = row.Col3
done
最终结果获得所有必需的数据。但这是运行了很长一段时间

我还尝试了如下的合并更新

    merge into emp t1
    using (select * from emp t where t.col4=X) t2
    on t1.col1=t2.col1
    and t1.col2=t2.col2
    and t1.col3=t3.col3
    when matched then update set col4=Y
and t1.col4!='X';
但这不会更新任何行


我真的非常感谢您对这个问题的帮助。

您尝试过一个简单的更新查询吗?您说的不清楚-哪些行必须更新为Col4=Y,哪些行当前为Col4=X,或者所有其他行?然后-不要在循环中执行此操作,不要使用游标等,这将需要两年时间才能完成。不要试图用锤子耙树叶;锤子是用来钉钉子的。用耙子耙树叶。也就是说:使用UPDATE语句(纯SQL,不需要像循环这样的过程代码)。我怀疑您显示的语句是否能够编译,至少有两个原因(那么“返回0行”是什么意思?)-首先,您不能设置col4=Y,它应该是='Y',第二,最后一行不合适(你是说t1…而不是t1…)然后:如果要有重复项,如何通过将col4中的值更改为“Y”,而不是现在的“X”,从而使col1-col4继续成为主键?即使语法正常,主键约束也应该拒绝大多数更改。需求本身没有意义!直接的更新查询通常是最简单的查询最快。如果您需要更快的速度,您需要更改物理布局,例如分区。但我不确定您是否完全描述了要编写的实际规则。@mathguy抱歉。我想我没有清楚地提出我的问题。我已经更新了问题。希望问题清楚。我不确定如何使用简单的更新和避免编写循环语句。您是否尝试过简单的更新查询?您所说的不清楚-哪些行必须更新为Col4=Y,哪些行当前为Col4=X,或者所有其他行?然后-不要在循环中执行此操作,不要使用游标等,这将需要两年才能完成。不要尝试用锤子耙树叶;锤子是用来钉钉子的。耙使用UPDATE语句(纯SQL,不需要像循环这样的过程代码)。我怀疑您显示的语句是否能够编译,至少有两个原因(您所说的“返回0行”是什么意思?)-首先,您不能设置col4=Y,它应该是='Y',第二,最后一行不合适(你是说t1…而不是t1…)然后:如果要有重复项,如何通过将col4中的值更改为“Y”,而不是现在的“X”,从而使col1-col4继续成为主键?即使语法正常,主键约束也应该拒绝大多数更改。需求本身没有意义!直接的更新查询通常是最简单的查询最快。如果您需要更快的速度,您需要更改物理布局,例如分区。但我不确定您是否完全描述了要编写的实际规则。@mathguy抱歉。我想我没有清楚地提出我的问题。我已经更新了问题。希望问题清楚。我不确定如何使用简单的更新和避免编写循环语句。
select *
  from emp x
 where x.col4 != 'X'
   and exists (select 1
                 from emp y
                where x.col1 = y.col1
                  and x.col2 = y.col2
                  and x.col3 = y.col3
                  and y.col4 = 'X')