Sql 插入需要事务处理的Select语句

Sql 插入需要事务处理的Select语句,sql,sql-server,Sql,Sql Server,我有一个存储过程,用于存储来自各地的ETL数据,最后尝试将所有数据连接到一个大表中。大约100列宽,3500万行 当我从临时表中提取并将其连接在一起时,插入查询可能需要几个小时、从页面到磁盘等。对于我的环境来说,它实在太大了 Insert Into tbl_huge Select Distinct a, b, c, d, e, f, g, h, i, j, k from (Mess of Subqueries & #tmp_tbls) 批处理此插入以一次提交10万行或

我有一个存储过程,用于存储来自各地的ETL数据,最后尝试将所有数据连接到一个大表中。大约100列宽,3500万行

当我从临时表中提取并将其连接在一起时,插入查询可能需要几个小时、从页面到磁盘等。对于我的环境来说,它实在太大了

Insert Into tbl_huge
    Select Distinct a, b, c, d, e, f, g, h, i, j, k
    from (Mess of Subqueries & #tmp_tbls) 
批处理此插入以一次提交10万行或其他内容的最佳方法是什么?数据中没有很好的自然键,即使是半均匀地分解,我担心这是真的

我看到过不同的例子使用了目标表中不存在的where,但这似乎是错误的方法,不会继续扩展和增长

那么,这里最好的方法是什么?对结果进行排序,并在while循环中多次重新执行Select&insert查询,保留一个计数器以知道我需要执行rows>x


有没有更好的方法,可以让我准确地选择要插入的子集,或者根据大小预处理select into memory+页面文件,并将其读回以分块插入?

ETL是提取、转换和加载。你在一个步骤中完成了所有这些,需要三个步骤

您确实需要在转换数据之前提取数据,然后加载到一个庞大的表中

为混乱的子查询和tmp_TBL创建固定表而不是临时表,以便将数据提取到其中。 将原始数据加载到这些表中如果所有数据都在一台服务器上或在同一数据库中,则可以跳过此步骤

然后将数据转换为插入所需的形状

完成后,加载它

如果这些步骤中的任何一个花费的时间太长,您可以考虑将单个步骤分块

它需要更多的工作,但更健壮


编辑:通常在以这种方式加载数据时,它基于一个日期,即将昨天的所有数据移动到仓库中,如果这是问题的一部分,您可以更频繁地运行加载。如每小时甚至每5分钟一次,您可以按照以下步骤分批进行插入

创建一个具有RowNumber标识列的临时表,以获得以下结果集。 创建表TENTABLETOHOLDRESULTSTROWNUMBER Int IDENTITY1,1,OtherColumns。。。 将结果集插入步骤1中创建的临时表中 插入到试探性的ToHoldResultsTother列中。。。 选择不同的a、b、c、d。。。从混乱的子查询和tmp_TBL 现在,使用While循环执行批插入。您可以使用 声明@minRowNumber INT=1 声明@batchsize INT=10000 声明@maxRowNumber INT 设置@maxRowNumber=@minRowNumber+@batchSize 当存在时,从DentiableToHoldResultSet中选择*,其中RowNumber>= @minRowNumber和RowNumber<@maxRowNumber 开始 设置XACT_中止,不计数为ON 声明@starttrancount int 开始尝试 选择@starttrancount=@@TRANCOUNT 如果@starttrancount=0 开始交易 插入tbl_中 选择a、b、c、d。。。从TestableToHoldResultSet 其中RowNumber>=@minRowNumber和RowNumber<@maxRowNumber; 设置@minRowNumber=@maxRowNumber 设置@maxRowNumber=@minRowNumber+@batchSize 如果@starttrancount=0 提交事务 结束尝试 开始捕捉 如果XACT_状态为0且@starttrancount=0 回滚事务; 投 -在SQL Server 2012之前使用 -RAISERROR[使用@ErrorNumber、@ErrorMessage等重新显示捕获的错误] 端接 终止 去 数据加载完成后,可以删除临时表。 -数据加载完成后,删除临时表 DROP TABLE TestableToHoldResultSet 去
我首先要考虑的事情之一是,您是否可以以一种可以消除对SELECT DISTINCT的需要的方式重新组织混乱的子查询和tmp_TBL。如果有什么事情导致您耗尽资源,那就是它。我的强烈建议是,使用您选择的应用程序语言在DB之外组装数据更改,然后一次发送10K行,即使我获取了所有数据,我也不确定在从一组连接完成插入时如何分块插入?我会有基本相同的问题,不是吗?这是一个正确的观点,但我们不知道这是否必要。可能是将数据加载到临时表需要花费所有的时间,而从临时表插入数据会非常快?虽然有3500万行的宽表可能会有问题,但通过将其拆分为多个语句和步骤,您可以隔离问题所在并优化查询的这些部分。