我有一个具有580 M条记录的表。我下面的代码似乎在一个多小时后超时,并且SQL Developer无法响应。有没有更有效的方法来添加一列随机数?
create table bigTable (
ID_KEY CHAR(64 BYTE),
randNum decimal(4,3)
);
-- insert ID_KEY value for 580M records (not shown)
UPDATE /*+PARALLEL(16)*/ bigTable
SET randNum = CAST(DBMS_RANDOM.VALUE(0,1) AS DECIMAL(4,3));
COMMIT;
答案 0 :(得分:4)
我为您提供CTAS来处理如此大的数据。 例如,您可以编写
create table bigTable as
select ID_KEY , CAST(DBMS_RANDOM.VALUE(0,1) AS DECIMAL(4,3)) randNum
from YOUR_TABLE_WHERE_ID_COMES_FROM;
我认为您的问题可能出在REDO文件的管理上,尽管如此,重做文件的大小取决于硬盘的写入速度以及许多其他原因,因此保持此类大数据的更改日志可能会导致问题。
关于@MarcinJ回答,使用很多提交可能会引起另一个问题,提交后需要时间将数据刷新到表中,这样才能使口头将数据写入硬盘,重写重做等等,所有这些都可能增加执行时间。
答案 1 :(得分:0)
最有可能获取此日志,因为您试图在单个事务中完成所有操作,这意味着它将变得非常大。如果可能,您可以尝试分批更新表格,例如一次一百万行。然后,您可以循环直到没有记录具有空randNum。像这样:
DECLARE
rowsAffected INTEGER := 1;
BEGIN
WHILE rowsAffected <> 0 LOOP
UPDATE bigTable
SET randNum = CAST(DBMS_RANDOM.VALUE(0,1) AS DECIMAL(4,3))
WHERE randNum IS NULL
AND rownum < 1000000;
rowsAffected := sql%rowcount;
COMMIT;
END LOOP;
END;
首先使用单个查询进行尝试,目前我无法访问Oracle数据库进行测试。
答案 2 :(得分:0)
在UPDATE
之前运行以下命令,以完全并行化SQL语句:
alter session enable parallel dml;
如果您使用的是12c或更高版本,则可以在提示中更改该设置,如下所示:
UPDATE /*+PARALLEL(16) ENABLE_PARALLEL_DML*/ ...
Seyran的答案仍然是进行大型更新的最有效的方法。您可以通过添加PARALLEL
提示和NOLOGGING
选项使他的回答更快。
但是,如果您要处理大型数据集,那么现在不妨了解一下完全并行化语句的重要性。原始的UPDATE
几乎没有使用并行性。缺乏并行性令人困惑,因为您可能会在GV$PX_PROCESS
中看到许多并行会话正在使用,甚至在执行计划中甚至可能会看到一些PX
操作,如下所示:
Plan hash value: 1905498248
------------------------------------------
| Id | Operation | Name |
------------------------------------------
| 0 | UPDATE STATEMENT | |
| 1 | UPDATE | BIGTABLE |
| 2 | PX COORDINATOR | |
| 3 | PX SEND QC (RANDOM)| :TQ10000 |
| 4 | PX BLOCK ITERATOR | |
| 5 | TABLE ACCESS FULL| BIGTABLE |
------------------------------------------
不幸的是,Oracle有时可以分配并行进程,但不能有意义地并行使用。
完全并行化的语句应在DML操作之上具有PX
操作。您希望看到如下执行计划。它与上面的执行计划仅稍有不同,但运行速度可能快将近16倍。
Plan hash value: 1693571574
------------------------------------------
| Id | Operation | Name |
------------------------------------------
| 0 | UPDATE STATEMENT | |
| 1 | PX COORDINATOR | |
| 2 | PX SEND QC (RANDOM) | :TQ10000 |
| 3 | UPDATE | BIGTABLE |
| 4 | PX BLOCK ITERATOR | |
| 5 | TABLE ACCESS FULL| BIGTABLE |
------------------------------------------
答案 3 :(得分:-3)
对于Interger
DECLARE @RandomNumber AS INT
Select @RandomNumber= FLOOR(RAND()*(2500-10+1))+1000;
PRINT @RandomNumber
Insert into Student(RollNumber)values(@RandomNumber)
提示::此公式将生成一个随机整数,该整数>> 1000和<= 2500。
您可以根据需要更改值,还可以生成浮点数和双数
谢谢!!!!