You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSIS中Aggregate ADO.Net源统计结果插入SQL Server的最优方案

10亿行级表当月每日行数统计插入SQL Server最优方案

核心优化逻辑:你统计的是当月每日行数,最终输出最多31条数据,优化重点是减少源表扫描开销、避免不必要的数据跨层流转。


场景1:ADO.NET数据源与目标SQL Server支持跨库查询(同实例/已配置链接服务器)

这是性能最优的方案,所有运算都在数据库引擎层完成,无额外数据传输开销,直接使用INSERT ... SELECT语句即可,你原有语句的INSERT顺序错误,修正后如下:

INSERT INTO dbo.OLEDB_Inegrated (activityDate, RecCount)
SELECT
    g.[ActivityDate], 
    COUNT(*) RecCount
FROM 
    [lab10].[ADONETSource_Integrated] g
-- 若无特殊业务日期规则,可去掉DimDate关联直接过滤,减少表关联开销
WHERE
    g.ActivityDate >= DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)
    -- 可选:如果只统计已结束的日期,避免当天未闭合数据被统计,加下面这行
    -- AND g.ActivityDate < CAST(GETDATE() AS DATE)
GROUP BY
    g.[ActivityDate]
-- 插入不需要排序,去掉原有ORDER BY减少排序开销

额外优化点:

  • 源表ADONETSource_Integrated的ActivityDate列必须创建非聚集索引,可直接走索引范围扫描,避免10亿行全表扫描,性能提升可达数百倍
  • 如果需要避免任务重复执行导致的重复插入,可增加判重逻辑:
INSERT INTO dbo.OLEDB_Inegrated (activityDate, RecCount)
SELECT
    g.[ActivityDate], 
    COUNT(*) RecCount
FROM 
    [lab10].[ADONETSource_Integrated] g
WHERE
    g.ActivityDate >= DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)
    AND NOT EXISTS (
        SELECT 1 FROM dbo.OLEDB_Inegrated t WHERE t.activityDate = g.ActivityDate
    )
GROUP BY
    g.[ActivityDate]

场景2:ADO.NET数据源无法与目标SQL Server直接跨库查询

方案A:用ETL工具实现

使用SSIS、Azure Data Factory等ETL工具:

  • 源配置为ADO.NET数据源,执行你编写的统计查询语句
  • 目标配置为SQL Server目标,启用批量插入模式,因为最终结果只有几十行,单次即可完成插入

方案B:自定义代码实现

如果用C#等语言自定义开发,使用SqlBulkCopy类完成批量插入:

  1. 用ADO.NET从源库查询出统计结果,存入DataTable或者DataReader
  2. 调用SqlBulkCopy直接批量写入目标SQL Server,性能远高于逐行执行INSERT语句

通用优化建议

  • 如果是每日定时调度任务,不需要每次统计全月数据,只统计前一天的行数即可,进一步缩小源表扫描范围
  • 目标表如果有除了ActivityDate之外的非聚集索引,当前数据量下可以忽略优化,若后续统计数据量变大可临时禁用索引,插入完成后再重建

内容的提问来源于stack exchange,提问作者SJJ9166

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 05:54:01