【发布时间】:2016-11-28 17:11:25
【问题描述】:
我正在处理一个包含许多字段和 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
finalresult 以获得所有必需的数据。但这运行了很长时间。
我也尝试合并更新如下
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',第二个最后一行不合适(你是说WHERE t1....而不是AND t1....?) 那么:col1-col4 会怎样如果您要重复主键,通过将 col4 中的值更改为“Y”(现在不是“X”),继续作为主键吗?即使您使语法有效,主键约束也应该拒绝大多数更改。要求本身没有意义!
-
直接更新查询通常是最快的。如果您需要它更快,您将需要更改物理布局,例如有分区。但我不确定你是否完全描述了你想要编码的实际规则是什么。
-
@mathguy 对不起。我想我没有清楚地提出我的问题。我已经更新了这个问题。希望很清楚。我不知道如何使用简单的 UPDATE 和避免循环语句来编写。