SQL Server使用检查优化批量保存

时间:2011-10-24 10:39:12

标签: sql-server

我需要保存一批对象。

性能缓慢(15分钟内保存了15万个对象)是由于检查。

检查每个对象 - 某些字段的聚合应该是唯一的。

所以问题是:

  • 如果我使用这些字段的哈希值创建其他索引列并在详细检查之前检查该列会有帮助吗?
  • 还有其他解决方案吗?

1 个答案:

答案 0 :(得分:0)

假设您当前正在逐行检查,并且在更新期间锁定表不是问题,我猜您在这里尝试做一个特殊的UPSERT(如果已经有匹配的行会发生什么情况) ?你是中止这个过程,还是跳过这一行,还是其他什么东西?)

在SQL Server 2008中,您可能正在寻找MERGE语句。

在SQL Server 2005及更早版本中,您可以使用LEFT JOIN执行类似操作(联接表中的键列为空)


更新(d两次):根据您的反馈,我们假设您正在使用SQL Server 2005并希望基于复合(多列)键添加新行,同时避免(并可能警告)现有/重复的行。

你有一个表“Table1”,其中包含一些数据:

KeyCol1  KeyCol2   ValueCol
1        2         Test
3        2         MoreTest
4        2         TestForever

您有一个包含要加载的数据的临时表(或表变量,或加载/登台表或其他内容):

KeyCol1  KeyCol2  ValueCol
2        2        OKValue
5        2        AlsoOK
4        2        ProblemValue

您执行内部联接以获取任何“已存在”的行(然后引发错误,或对问题条目列表执行任何操作):

SELECT FinalTable.* 
INTO #ProblemRecords
FROM FinalTable 
INNER JOIN TempTable ON FinalTable.KeyCol1 = TempTable.KeyCol1
    AND FinalTable.KeyCol2 = TempTable.KeyCol2
--Could add group by here if it's possible to have more than one record per join key

左边连接用于插入在最终表格中具有已匹配记录的记录:

INSERT INTO FinalTable (KeyCol1, KeyCol2, ValueCol)
SELECT TempTable.KeyCol1, TempTable.KeyCol2, TempTable.ValueCol)
FROM TempTable
LEFT JOIN FinalTable ON FinalTable.KeyCol1 = TempTable.KeyCol1
    AND FinalTable.KeyCol2 = TempTable.KeyCol2
WHERE FinalTable.KeyCol1 Is Null

关于这种方法的一些注意事项:

  • 为了安全起见,您需要引入大规模锁定(为简单起见,我在这里省略了事务)。对于需要保持可用且响应迅速的OLTP系统而言,这可能是一个问题。
  • 当它正在运行时,它会比你的“缓慢但肯定会这样”的方法使用更多的资源。
  • 不知何故,您需要将数据放入临时/加载表中。某种批量加载过程可能有意义(请参阅BULK INSERTbcpSQLXML,SSIS /导入 - 导出向导等等。