如何在SQL Server 2005中有效地操作500k记录?

时间:2010-03-24 14:49:45

标签: sql-server-2005 timeout

我从客户那里收到一个包含500,000个用户更新的更新信息的大文本文件。但是,当我处理此文件时,我经常遇到SQL Server超时错误。

以下是我在VB应用程序中遵循的处理数据的过程(通常):

  1. 删除临时表中的所有记录(删除上个月的数据)(例如DELETE * FROM tempTable
  2. 将文本文件翻录到临时表
  3. 在临时表中填写额外信息,例如他们的organization_id,他们的user_id,group_code等。
  4. 根据临时表中计算的数据更新实际表中的数据
  5. 问题是我经常运行像UPDATE tempTable SET user_id = (SELECT user_id FROM myUsers WHERE external_id = tempTable.external_id这样的命令,这些命令经常超时。我已经尝试将时间超过10分钟,但它们仍然失败。现在,我意识到500k行是不容易操作的行数,但我认为据称能够处理数百万行的数据库应该能够很容易地处理500k。我对如何处理这些数据做错了吗?

    请帮忙。任何和所有建议都欢迎。

6 个答案:

答案 0 :(得分:5)

像你在问题中给我们的那些子查询:

UPDATE tempTable SET user_id = (SELECT user_id FROM myUsers WHERE external_id = tempTable.external_id) 

一次只能在一行上好,所以你必须循环。基于思考集:

UPDATE t
    SET user_id = u.user_id
    FROM tempTable          t
        inner join myUsers  u ON t.external_id=u.external_id

并删除你的循环,这将更新一个语句中的所有行,并且明显更快!

答案 1 :(得分:1)

需要更多信息。我经常在1.5亿行表中操作3-4百万行,我不认为这是很多数据。我有一个“产品”表,其中包含大约800万条目 - 包括全文搜索。没问题。

你能详细说明你的硬件吗?我假设“普通台式PC”或“低端服务器”,两者都具有绝对非最佳的光盘布局,因此有大量的IO问题 - 更新时。

答案 2 :(得分:1)

您是在导入数据后索引临时表吗?

temp_table.external_id肯定应该有一个索引,因为它在where子句中。

答案 3 :(得分:1)

确保您正在执行选择的表上有索引。在示例UPDATE命令中,从myUsers表中选择user_id。你在myUsers表上有一个带有user_id列的索引吗?索引的缺点是它们增加了插入/更新的时间。确保您尝试更新的表上没有索引。如果您尝试更新的表确实有索引,请考虑删除它们,然后在导入后重建它们。

最后,在SQL Server Management Studio中运行查询,并查看执行计划以查看查询的执行方式。查找表扫描等内容,了解您可以优化的位置。

答案 4 :(得分:1)

查看KM的答案,不要忘记索引和主键。

答案 5 :(得分:-1)

有更有效的方法可以导入大块数据。在BCP(批量复制协议)下查看SQL联机丛书。