更新具有数百万条记录的表,迄今已有4天


12

我当前正在更新具有数百万条记录的表,该表已经进行了4天,并且查询仍在执行。

我检查了活动监视器,它显示查询正在运行。

在事件日志中根本没有错误。

性能明智:

  • 磁盘A中的Tempdb(850 GB可用空间)
  • 磁盘B中的数据库文件(750 GB可用空间)
  • 16 GB内存

请建议我该怎么办?

查询

UPDATE
    dbo.table1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
    dbo.table2 t2
WHERE
    LEFT(dbo.test1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

Answers:


3

这个查询有一个有趣的细节,我一开始没有发现。感谢Fabricio Araujo的回答,现在我看到了:您正在访问两个表。我以前从未见过这种更新语句的用法,我不建议您使用它。我建议您根据Fabricio的答案使用更直观的连接语法。

可能的原因是两个表之间的联接产生了过多的行。如果LEFT(col, 3)表达式产生重复值,则可能会发生这种情况。如果产生10个重复项,则连接结果将导致100000x100000 = 10000000000行。

我认为索引在这里不起作用。SQL Server可以使用哈希或合并联接很好地解决此未索引联接。不需要4天。

另一个可能的原因是联接输入或输出的基数低估。SQL Server可能选择了循环联接。

由于这仍然是推测,因此建议您发布查询计划,以阐明该问题。


8

此查询要求您扫描表中的每一行,因为

  • 我猜procodet或ProviderCode没有索引
  • 即使它们已被索引,您也具有LEFT,它是WHERE谓词上的函数
  • 而且您也具有COLLATE,这实际上是WHERE谓词上的函数

“ WHERE谓词上的函数”表示将不使用索引

如果您对它进行批处理(例如,对UPDATE TOP(10000)... AND costPercentage为NULL),则需要在costPercentage上建立一个索引,假设您正在设置它。

我看到的唯一解决方案是

  • 例如,根据主键分批填充一个新表
  • 创建索引的计算列以隐藏LEFT和COLLATE表达式,然后运行更新

@ gbn ..谢谢,这是个好主意..但是由于数据量很大,所以这个过程将需要时间....我以为可能有办法找出查询的进度?
幸运

1
为什么要扫描4百万行需要4天?不管行有多大且索引多少,这都不需要4天。问题的根源仍然未知。
usr

1
如果您定期处理大数据,那么您将为此获得合适的服务器呢?将数据放在SSD等
TomTom,

1
@幸运的是。我正在回答答案。我们还没有发现错误。它本身不是查询,也不是硬件查询。那将永远不会长达4天。
usr

3
假设查询将一列的3个字符部分连接到另一列的3个字符部分,则结果将很可能包含重复项。这比仅更新数百万行要差得多。我敢打赌它正在扫描数十亿的工作表。
datagod

4

首先,将查询更改为:

UPDATE t1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
  dbo.table1 t1
  inner join dbo.table2 t2
    on LEFT(t1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

根据Jeff Moden 在该讨论中的第一篇文章所述,您的查询与他警告“万圣节效应”的查询非常相似。

在那之后,那些左表达式必须被索引。gbn的答案为您提供了如何执行此操作的指示。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.