高斯数据库批量插入50w不重复的数据sql
时间: 2025-09-12 18:48:29 AIGC 浏览: 2
在 GaussDB 中执行批量插入 500,000 条不重复数据的操作时,推荐使用高效且可控的方式,以避免事务过大、内存溢出或性能下降等问题。以下是一种结合 PL/pgSQL 的分批插入实现方式,并确保数据唯一性。
### 1. 使用临时表进行数据预处理
在插入之前,可以先将数据加载到一个临时表中,再通过 `INSERT INTO ... SELECT` 语句将去重后的数据插入目标表中。
```sql
-- 创建临时表
CREATE TEMP TABLE temp_data (
id INT PRIMARY KEY,
name TEXT,
created_at TIMESTAMP
);
-- 假设通过 COPY 或其他方式将数据加载到临时表中
COPY temp_data FROM '/path/to/data.csv' DELIMITER ',' CSV HEADER;
-- 插入主表并去重(假设主表为 target_table,已存在)
INSERT INTO target_table (id, name, created_at)
SELECT id, name, created_at
FROM temp_data
WHERE id NOT IN (SELECT id FROM target_table);
```
### 2. 使用 PL/pgSQL 实现分批插入
当数据量较大(如 50 万条)时,建议使用分批处理机制以减少事务日志压力和锁竞争。
```sql
DO $$
DECLARE
batch_size INT := 5000; -- 每批插入的数据量
total_rows INT := 500000; -- 总共要插入的行数
start_id INT := 1;
BEGIN
WHILE start_id <= total_rows LOOP
INSERT INTO target_table (id, name, created_at)
SELECT
generate_series(start_id, LEAST(start_id + batch_size - 1, total_rows),
('Name' || generate_series)::TEXT,
NOW()
ON CONFLICT (id) DO NOTHING; -- 确保不重复插入主键冲突的数据
RAISE NOTICE 'Inserted batch from % to %', start_id, LEAST(start_id + batch_size - 1, total_rows);
start_id := start_id + batch_size;
END LOOP;
END;
$$;
```
### 3. 使用 `COPY` 命令进行高效导入
如果数据源是文件(如 CSV),推荐使用 `COPY` 命令导入,然后通过 `ON CONFLICT DO NOTHING` 处理重复数据[^3]。
```sql
-- 导入到临时表
COPY temp_data FROM '/path/to/data.csv' DELIMITER ',' CSV HEADER;
-- 插入主表并跳过重复主键
INSERT INTO target_table (id, name, created_at)
SELECT id, name, created_at
FROM temp_data
ON CONFLICT (id) DO NOTHING;
```
### 4. 提高性能的建议
- **关闭自动提交**:在批量插入时,使用事务控制避免频繁提交。
- **关闭索引/约束**:插入前可暂时禁用索引,插入完成后重新启用。
- **调整事务日志配置**:如增大 `max_wal_size` 以适应大批量写入。
- **并行执行**:在支持并行的版本中,可使用并行查询提升性能[^2]。
---
阅读全文
相关推荐

















