十万行事务锁,开了眼界了。

博客提到一个程序存在十万行事务锁,提交速度极慢。经检查发现事务开启后,既未commit也未rollback,直接return,反映出程序在事务处理上存在严重问题。

不大一个程序,十万行事务锁,提交一次慢的不行,一查竟然10万多行事务锁,真是开了眼界了。

 事务开了,没有commit也没有rollback,直接就return走了人,服了服了

<think> 我们正在处理用户关于使用Oracle的rownum插入十万数据的问题。根据引用[2],其中提到了使用dual配合connect by level来生成大量数据。在Oracle中,`connect by level`是一个常用的生成序列或大量的方法。 用户需要插入十万数据,我们可以使用类似的方法。引用[2]中的示例是创建表并插入1万条数据,我们可以扩展这个方法来生成十万条。 基本思路: 1. 使用`select ... from dual connect by level <= N` 来生成N数据(这里N=100000)。 2. 我们可以直接在一个插入语句中使用这个方法来向目标表插入数据。 但是,需要注意的是,直接使用`connect by level`生成大量数据时,可能会受到Oracle的递归查询深度的限制(默认是50)。为了避免这个问题,我们可以调整session的递归深度,或者使用更高效的方法(例如,使用多个层次交叉连接)。 然而,对于十万数据,我们可以通过设置递归深度为100000,但这样效率可能不高。另一种方法是使用两层或多层交叉连接,例如: ```sql insert into target_table (id) select rownum from dual connect by level <= 100000; ``` 但是,实际上,当数据量达到十万时,使用单层`connect by`可能会比较慢,而且可能超出递归深度限制。因此,我们可以采用两个或多个`connect by`交叉连接的方式,例如: ```sql insert into target_table (id) select rownum from (select 1 from dual connect by level <= 1000) a, (select 1 from dual connect by level <= 100) b where rownum <= 100000; ``` 这里,我们生成了1000和100的两个结果集,然后做笛卡尔积(得到100000),然后取rownum作为id。 但注意,rownum是从1始递增的整数,这样我们就得到了1到100000的连续数字。 另外,如果用户需要插入的数据不仅仅是id,还可以在select语句中构造其他列。 步骤: 1. 创建目标表(如果不存在的话)。假设我们只需要一个id列,那么创建表语句可以是: ```sql create table target_table (id number); ``` 2. 使用上述插入语句插入数据。 但是,用户可能已经存在表,那么只需插入数据即可。 考虑到用户可能已经存在表,并且可能有其他列,这里我们假设用户只需要插入id列(或者用户表的结构未知)。因此,我们给出一个通用的插入方法,即只插入id列,其他列可以按需调整。 如果用户需要插入的数据有其他列,那么需要根据实际情况调整select语句,例如为其他列提供默认值或固定值。 因此,我们可以这样写: ```sql -- 假设目标表为target_table,有id列和其他列(如需要,可以设置默认值或固定值) insert into target_table (id, col1, col2, ...) select rownum, 'value1', 'value2', ... from dual connect by level <= 100000; ``` 或者,如果使用两层连接: ```sql insert into target_table (id, col1, col2, ...) select rownum, 'value1', 'value2', ... from (select 1 from dual connect by level <= 1000) a, (select 1 from dual connect by level <= 100) b where rownum <= 100000; ``` 注意:在第二层连接中,我们使用两个子查询的笛卡尔积得到1000*100=100000,然后取rownum(注意rownum会从1始递增)。 但是,如果用户只需要插入10万,并且id列是连续的,那么这种方法可以。 另外,我们也可以使用PL/SQL循环插入,但效率可能不如直接使用SQL语句。 根据引用[2]的示例,我们可以直接使用`connect by`方法,因此我们推荐使用SQL语句插入。 因此,回答如下: </think> ### 使用 Oracle ROWNUM 插入十万数据的方法 在 Oracle 中,使用 `ROWNUM` 结合 `CONNECT BY` 子句可以高效生成大量数据。以下是两种常用方法: #### 方法 1:基础插入(推荐) ```sql INSERT INTO 目标表名 (id, 其他列...) SELECT ROWNUM AS id, -- 生成连续ID '固定值' AS 列1, -- 自定义其他列值 SYSDATE AS 时间列 -- 示例:插入当前时间 FROM dual CONNECT BY ROWNUM <= 100000; -- 生成10万 ``` **特点**: - 单条 SQL 完成插入,效率最高 - 通过 `CONNECT BY ROWNUM <= N` 控制数 - 支持自定义列值(如固定字符串、序列、函数等) #### 方法 2:分步操作 ```sql -- 步骤1:创建含ROWNUM的临时表 CREATE TABLE temp_table AS SELECT ROWNUM AS id FROM dual CONNECT BY ROWNUM <= 100000; -- 步骤2:插入目标表 INSERT INTO 目标表名 (id, 其他列) SELECT id, '数据' || id -- 拼接动态数据示例 FROM temp_table; -- 步骤3:清理临时表(可选) DROP TABLE temp_table; ``` **适用场景**: - 需要复杂数据处理时 - 需重用生成的数据集 ### 关键注意事项 1. **性能优化**: - 10万插入建议添加 `/*+ APPEND */` 提示启用直接路径插入: ```sql INSERT /*+ APPEND */ INTO 目标表名 ... ``` - 执后需 `COMMIT` 提交事务 2. **自定义数据规则**: ```sql SELECT ROWNUM, CASE WHEN MOD(ROWNUM, 2)=0 THEN 'A' ELSE 'B' END, -- 条件赋值 DBMS_RANDOM.STRING('X', 10) -- 随机字符串 FROM dual CONNECT BY ROWNUM <= 100000; ``` 3. **替代方案**: ```sql -- 使用递归WITH(Oracle 12c+) WITH gen(id) AS ( SELECT 1 FROM dual UNION ALL SELECT id+1 FROM gen WHERE id < 100000 ) SELECT id FROM gen; ``` > **重要提示**: > 实际执前建议在测试环境验证,大数据量插入需考虑表空间和undo空间是否充足[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值