0-Oracle测试插入10W条数据

0-Oracle测试插入10W条数据

--sql
--创建测试用户
create user test identified by test;
--授权
grant dba to test;
--创建表
create table test.T1(ID NUMBER,AT DATE);
--创建存储过程,以“/”结束
create or replace procedure test.test (cnt in number) as
i NUMBER;
begin
for i in 1..cnt loop
INSERT INTO T1 VALUES(i,SYSDATE);
commit;
end LOOP;
END;
/

--插入10W条
exec test.test(100000);

<think>我们正在讨论达梦数据库(DM)中批量插入数据的方法。根据引用内容,我们可以总结出几种常见的批量插入方式: 1. **使用存储过程循环插入**(引用[2]): - 通过声明变量控制循环次数,逐插入数据- 示例:插入100数据,但效率较低,因为每次循环都要执行一次插入。 2. **使用`INSERT INTO ... SELECT`结合伪表和`CONNECT BY`生成大量数据**(引用[3]): - 利用达梦数据库的`dual`伪表和`CONNECT BY`语法生成指定行数的数据- 示例:通过`connect by level <= 10000000`生成1000万行数据,并利用随机函数生成各列的值。 3. **使用`MERGE INTO`语句进行批量插入(并可忽略主键重复)**(引用[1]的标题提到,但具体内容未给出,根据标题我们可以推测这是一种高级用法): - `MERGE INTO`通常用于合并数据(更新或插入),但也可以用于批量插入并处理重复键(例如忽略重复)。 下面我们详细说明这三种方法: ### 方法1:存储过程循环插入 这种方法适用于数据量不是特别大(例如几万)的情况,对于百万级以上数据量效率较低。 示例(来自引用[2]): ```sql DECLARE i INT := 1; BEGIN LOOP i := i+1; INSERT INTO dm_varchar (aes, sm4, sm4_a, email, phone, ssn, military, credit_card, job) VALUES ('胡小芬', '北京xx网络技术有限公司', '北京市', 'xxx@yahoo.com', '15652996964', '210302199608124861', '武水电字第3632734号', '6227612145830440', '测试开发工程师'); EXIT WHEN i=1000000; END LOOP; END; / ``` ### 方法2:使用`INSERT INTO ... SELECT`和伪表生成大量数据 这是生成大量测试数据的高效方法,通过一SQL语句即可插入大量数据。 示例(来自引用[3],并稍作解释): ```sql INSERT INTO TMONTH_DATA(id, name, bir) SELECT rownum AS id, dbms_random.string('x', 10) || '大方扣扣的妈妈网' || dbms_random.string('x', 10) AS random_string, (TO_DATE('1991-01-01', 'YYYY-MM-DD') + DBMS_RANDOM.VALUE(0, SYSDATE - TO_DATE('1991-01-01', 'YYYY-MM-DD'))) FROM dual CONNECT BY LEVEL <= 10000000; ``` 说明: - `dual`:达梦数据库中的伪表,用于生成数据- `CONNECT BY LEVEL <= n`:生成n行数据- `dbms_random.string('x', 10)`:生成10个由大写字母和数字组成的随机字符串。 - `DBMS_RANDOM.VALUE(a, b)`:生成a到b之间的随机数,这里用于生成随机日期。 ### 方法3:使用`MERGE INTO`忽略重复主键插入 `MERGE INTO`语句通常用于根据源表数据更新或插入目标表。我们可以利用它来插入数据,并在遇到主键重复时忽略(不做任何操作)。 示例(假设目标表为`target_table`,源数据来自一个子查询或临时表): ```sql MERGE INTO target_table t USING ( -- 这里构造批量数据,可以是一个子查询或者临时表 SELECT ... FROM dual CONNECT BY ... ) s ON (t.primary_key = s.primary_key) -- 根据主键匹配 WHEN NOT MATCHED THEN INSERT (col1, col2, ...) VALUES (s.col1, s.col2, ...); ``` 注意:这种方法需要有一个匹配件(ON子句),并且只插入不匹配的行(即主键不重复的行)。这样可以避免主键重复错误。 ### 性能比较 - 存储过程循环插入:效率最低,适合小批量数据- `INSERT INTO ... SELECT`:效率高,适合生成大量测试数据- `MERGE INTO`:效率较高,且可以处理重复数据,适合需要避免重复的批量插入。 ### 注意事项 1. **事务管理**:批量插入时,如果数据量很大,建议分批次提交事务,避免大事务导致回滚段膨胀和性能下降。 2. **日志记录**:批量插入会产生大量日志,可以适当调整日志参数(如加大日志文件大小)或使用`nologging`选项(但需谨慎,以防数据丢失无法恢复)。 3. **约束和索引**:在批量插入前,可以考虑暂时禁用约束和索引,插入完成后再重建,以提高性能。 ### 相关问题 1. 达梦数据库批量插入数据时如何提高性能? 2. 达梦数据库的`MERGE INTO`语句有哪些具体用法? 3. 如何避免批量插入时的主键重复错误? 4. 达梦数据库生成随机数据的方法有哪些?</think>### 达梦数据库(DM)批量插入数据方法详解 在达梦数据库中进行批量插入操作,主要有以下三种高效方法(附代码示例): --- #### 方法1:存储过程循环插入(适合精确控制数据量) ```sql DECLARE i INT := 1; -- 初始化计数器 BEGIN LOOP INSERT INTO dm_varchar (aes, sm4, email) VALUES ('张明', '上海科技', 'zhang@example.com'); --插入语句 i := i + 1; EXIT WHEN i > 1000000; -- 插入100后退出 END LOOP; COMMIT; -- 提交事务 END; ``` **特点**: -插入,逻辑简单直观[^2] - 需手动提交事务(`COMMIT`) - 性能较低,适合百万级以下数据 --- #### 方法2:伪表+`CONNECT BY`批量生成(千万级数据首选) ```sql INSERT INTO TMONTH_DATA(id, name, bir) SELECT ROWNUM, DBMS_RANDOM.STRING('X', 10) || '公司' || DBMS_RANDOM.STRING('X', 10), -- 随机字符串 TO_DATE('1990-01-01', 'YYYY-MM-DD') + DBMS_RANDOM.VALUE(0, 12000) -- 随机日期 FROM DUAL CONNECT BY LEVEL <= 10000000; -- 生成1000万行[^3] ``` **优势**: 1. **单SQL执行**:无需循环,效率提升10倍以上 2. **内置函数**: - `DBMS_RANDOM.STRING()` 生成随机字符串 - `DBMS_RANDOM.VALUE()` 生成随机数 3. `CONNECT BY LEVEL` 快速生成序列 --- #### 方法3:`MERGE INTO`忽略重复(安全写入) ```sql MERGE INTO target_table t USING ( SELECT '李雷' AS name, '深圳' AS address FROM dual UNION ALL SELECT '韩梅梅', '广州' FROM dual -- 可扩展更多数据行 ) s ON (t.name = s.name) -- 匹配件 WHEN NOT MATCHED THEN --插入不重复数据 INSERT (name, address) VALUES (s.name, s.address); ``` **核心价值**: - 自动跳过主键/唯一键冲突[^1] - 支持多数据源(子查询/临时表) - 原子性操作(无需显式事务) --- ### ⚙️ 性能优化建议 1. **分批提交**:每50执行`COMMIT`避免大事务 ```sql FOR i IN 1..200 LOOP INSERT ... CONNECT BY LEVEL <= 50000; -- 每次5万 COMMIT; END LOOP; ``` 2. **禁用约束**:插入前禁用索引和约束 ```sql ALTER TABLE dm_varchar DISABLE CONSTRAINT CONS134215; -- 禁用约束 -- 执行批量插入 ALTER TABLE dm_varchar ENABLE CONSTRAINT CONS134215; -- 重新启用 ``` 3. **并行处理**: ```sql ALTER SESSION ENABLE PARALLEL DML; -- 启用并行 INSERT /*+ PARALLEL(4) */ INTO ... -- 使用4个并行线程 ``` --- ### 测试数据生成技巧 ```sql -- 生成1亿测试数据 INSERT INTO big_data SELECT ROWNUM, MOD(ROWNUM, 100), -- 取模分布 SYSDATE - DBMS_RANDOM.VALUE(1,3650), -- 10年内随机日期 RPAD('X', 200, 'Y') -- 200字节大字段 FROM DUAL CONNECT BY LEVEL <= 100000000; ``` --- ### 相关问题 1. 达梦数据库如何实现批量更新与插入的原子操作? 2. 使用`CONNECT BY`生成数据时如何避免内存溢出? 3. 达梦与Oracle在批量插入语法上有哪些兼容性差异? 4. 如何监控大规模数据插入的性能瓶颈? [^1]: 高级DBA教你达梦8国产数据库MergeInto批量插入并忽略主键重复报错特殊用法 [^2]: 达梦数据库使用存储过程批量插入100w数据 [^3]: DM达梦数据库快速生成1000w数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值