Oracle查询100万到200万之间的数据

本文介绍两种在SQL中选取特定区间数据的方法:一是利用分析函数row_number()结合partition by和order by进行精确排序;二是通过rownum虚列实现快速定位。这两种方法适用于不同场景,帮助开发者高效获取所需数据。

取100-150条数据的方法

1. 最佳选择:利用分析函数

        row_number() over ( partition by col1 order by col2 )                               

比如想取出100-150条记录,按照tname排序    

select tname,tabtype from (                               

            select tname,tabtype,row_number() over ( order by tname ) rn from tab                

         ) where rn between 100 and 150;   从第100条(包含第100条)到第150条数据,总共51条数据

2. 使用rownum 虚列

        select tname,tabtype from (                    

            select tname,tabtype,rownum rn from tab where rownum <= 150                  

         ) where rn >= 100;

查询100万到200万之间的数据:

select ID,
       CASEID,
       PERSONID,
       NAME,
       TYPE,
       STATE,
       ADDRESS,
       PHONENO,
       CONTACT,
       DRIVERLICENSEDOCID,
       DRIVERLICENSEISSUEOFFICE,
       SEX,
       AGE,
       WOUNDINFOID,
       DRIVINGAGE,
       DRIVERLICENSETYPEID,
       CONVEYANCEMEANSID,
       OUTINGPURPOSE,
       ISDRIVER,
       ISWEARINGSEATBELT,
       UPDATETIME,
       UPDATEACCOUNTID,
       PARTYUNIT,
       PERSONAREACODE,
       INJUREDPARTID,
       PERSONALTYPEID,
       ACCIDENTREASONID,
       BUSSINESSCERTIFICATION,
       CORPORATION,
       ESCAPETIME,
       BIRTHDAY,
       CORPERATIONSEX,
       CORPERATIONAGE,
       CORPERATIONADDRESS,
       CORPERATIONCONTACT,
       CORPERATIONIDNUMBER,
       LICENCE,
       MEMO,
       BCISSUER
  from (select ID,
               CASEID,
               PERSONID,
               NAME,
               TYPE,
               STATE,
               ADDRESS,
               PHONENO,
               CONTACT,
               DRIVERLICENSEDOCID,
               DRIVERLICENSEISSUEOFFICE,
               SEX,
               AGE,
               WOUNDINFOID,
               DRIVINGAGE,
               DRIVERLICENSETYPEID,
               CONVEYANCEMEANSID,
               OUTINGPURPOSE,
               ISDRIVER,
               ISWEARINGSEATBELT,
               UPDATETIME,
               UPDATEACCOUNTID,
               PARTYUNIT,
               PERSONAREACODE,
               INJUREDPARTID,
               PERSONALTYPEID,
               ACCIDENTREASONID,
               BUSSINESSCERTIFICATION,
               CORPORATION,
               ESCAPETIME,
               BIRTHDAY,
               CORPERATIONSEX,
               CORPERATIONAGE,
               CORPERATIONADDRESS,
               CORPERATIONCONTACT,
               CORPERATIONIDNUMBER,
               LICENCE,
               MEMO,
               BCISSUER,
               row_number() over(order by id) rn
          from TC_PARTY
         order by id)
 where rn between 1000001 and 2000000

从1000001到2000000,总共100万条数据

在使用 **Oracle 数据库**时,通过 C# 和 **SqlSugar** 插入 100 数据,由于 Oracle 不支持像 SQL Server 的 `SqlBulkCopy` 这样的原生批量加载机制,因此不能直接使用高效的“真正”的 bulk copy。 但 SqlSugar 提供了针对 Oracle 的优化方式:**分批插入 + 参数化 SQL 批量提交(模拟批量)**。我们可以通过配置来最大化性能。 --- ### ✅ 目标:使用 SqlSugar 在 Oracle 中高效插入 100 记录 > 使用技术: > - `Insertable().ExecuteCommand()` > - 分批处理(Batch Insert) > - 禁用日志、启用事务控制等性能优化 --- ### ✅ 示例代码:C# + SqlSugar 向 Oracle 插入 100W 数据 ```csharp using SqlSugar; using System; using System.Collections.Generic; // 实体类映射到 Oracle 表 public class User { [SugarColumn(IsPrimaryKey = true)] public string Id { get; set; } // Oracle 不常用自增列,这里用 Guid 字符串主键 public string Name { get; set; } public int Age { get; set; } public DateTime CreateTime { get; set; } } class Program { static void Main(string[] args) { var db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));User Id=myuser;Password=mypassword;", DbType = DbType.Oracle, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute }); // 创建表(首次运行) db.CodeFirst.InitTables<User>(); // 设置批大小(重要!) const int batchSize = 5000; // Oracle 推荐每批 2000~10000 const int total = 1_000_000; Console.WriteLine("开始生成并插入 100 数据..."); // 分批生成和插入,避免内存溢出 for (int i = 0; i < total; i += batchSize) { var batch = new List<User>(); for (int j = i; j < i + batchSize && j < total; j++) { batch.Add(new User { Id = Guid.NewGuid().ToString("N"), Name = $"User_{j}", Age = j % 100 + 1, CreateTime = DateTime.Now }); } // 关键:禁用 SQL 日志输出(大幅提升性能) db.Aop.OnLogExecuting = null; // 执行批量插入(底层生成 INSERT ALL INTO ... SELECT ... FROM DUAL 形式) db.Insertable(batch).ExecuteCommand(); Console.WriteLine($"已插入 {i + batch.Count} / {total}"); } Console.WriteLine("全部数据插入完成!"); } } ``` --- ### 🔍 代码解释与关键点说明: #### ✅ 1. `DbType.Oracle` - 指定数据库类型为 Oracle,SqlSugar 会自动适配 Oracle 的语法。 - 自动生成如 `INSERT ALL INTO ... INTO ... SELECT * FROM DUAL` 的多行插入语句。 #### ✅ 2. 分批插入(`batchSize = 5000`) - 避免一次性加载 100 对象进内存(OOM 风险)。 - Oracle 对单 SQL 长度有限制,过大 SQL 会报错,所以必须分批。 #### ✅ 3. `db.Aop.OnLogExecuting = null` - 关闭 SQL 日志打印,否则每 SQL 输出都会严重影响性能(可提升数倍速度)。 #### ✅ 4. `Insertable(list).ExecuteCommand()` - 在 Oracle 上,SqlSugar 自动将 List 转换为: ```sql INSERT ALL INTO users (ID, NAME, AGE, CREATETIME) VALUES ('...', 'User_1', 20, TO_DATE('2025-04-05', 'YYYY-MM-DD')) INTO users (ID, NAME, AGE, CREATETIME) VALUES ('...', 'User_2', 21, TO_DATE('2025-04-05', 'YYYY-MM-DD')) ... SELECT 1 FROM DUAL ``` 这是 Oracle 实现“伪批量插入”的标准做法。 #### ⚠️ 注意事项: - Oracle **没有真正的 Bulk API**(不像 SQL Server 的 `SqlBulkCopy`),所以最快也只能做到这种程度。 - 若追求极致性能,建议使用 **Oracle Data Provider for .NET (ODP.NET) 的 `OracleBulkCopy` 类** —— 但这不是 ORM 方式,且 SqlSugar 当前版本 **不内置支持 ODP.NET 的 Bulk 复制**(仅支持 Microsoft.Data.SqlClient)。 --- ### 🚀 性能优化建议(Oracle 批量插入) | 优化项 | 方法 | |-------|------| | 🔹 关闭日志 | `db.Aop.OnLogExecuting = null;` | | 🔹 使用事务(减少提交次数) | 包裹大事务或每批提交 | | 🔹 控制批次大小 | 建议 2000~10000,太大易失败 | | 🔹 使用连接池 | Oracle 默认开启,确保连接字符串正确 | | 🔹 异步插入? | 可用 `.ExecuteCommandAsync()`,但对吞吐帮助有限 | 示例:添加事务(每批提交一次) ```csharp db.Ado.UseTran(() => { db.Insertable(batch).ExecuteCommand(); }); ``` --- ### 📊 性能预期(参考) | 件 | 时间估算 | |------|---------| | Oracle 19c, SSD, i7 CPU, 批次 5000 | ~60~120 秒 | | 开启日志、小批次(1000) | ~200+ 秒 | --- ### ❗替代方案(更高性能):使用 `OracleBulkCopy`(非 SqlSugar) 如果你可以脱离 ORM,推荐使用 ODP.NET 的 `OracleBulkCopy`: ```csharp using (var bulkCopy = new OracleBulkCopy(connectionString)) { bulkCopy.DestinationTableName = "USER"; bulkCopy.WriteToServer(dataTable); // DataTable 快速写入 } ``` > ⛔️ 缺点:需要手动构建 `DataTable`,失去 ORM 便利性。 --- ### ✅ 总结 虽然 SqlSugar 在 Oracle 上无法使用真正的“bulk copy”,但通过以下方式仍可实现相对高效的百级插入: - 使用 `Insertable(list).ExecuteCommand()` 实现 `INSERT ALL` 批量插入 - 分批生成数据(防止内存溢出) - 关闭 AOP 日志 - 控制批次大小(5000 左右最佳) 这是目前 **使用 SqlSugar + Oracle 实现大批量插入的最优解**。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值