Luc*_*cky 12 sql-server-2008 sql-server
我目前正在更新一个包含数百万条记录的表,已经 4 天了,查询仍在执行。
我检查了活动监视器,它显示查询正在运行。
在事件日志中根本没有错误。
性能明智:
请建议我该怎么办?
查询
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
Run Code Online (Sandbox Code Playgroud)
此查询要求您扫描表中的每一行,因为
“WHERE 谓词上的函数”意味着不会使用索引
如果你批处理它(比如在 UPDATE TOP (10000) ... AND costPercentage IS NULL)那么你需要一个关于 costPercentage 的索引,这假设你正在设置它。
我看到的唯一解决方案是
这个查询有一个有趣的细节,我一开始没有发现。感谢 Fabricio Araujo 的回答,我现在明白了:您正在访问两个表。我以前从未见过更新语句的这种用法,我不建议使用它。我建议您根据 Fabricio 的答案使用更直观的连接语法。
可能的原因是两个表之间的联接产生了极端数量的行。如果LEFT(col, 3)
表达式产生重复值,则可能会发生这种情况。如果它产生 10 个重复项,这将导致连接结果中有 100000x100000=10000000000 行。
我不认为索引在这里发挥作用。SQL Server 可以使用散列或合并联接来很好地解决此未索引联接。不需要4天。
另一个可能的原因是低估了连接输入或输出的基数。SQL Server 可能选择了循环连接。
由于这仍然是猜测,我建议您发布查询计划,这将阐明这个问题。