【问题标题】:How to improve t-sql performance for statement containing IsNull(NullIf(...))如何提高包含 IsNull(NullIf(...)) 的语句的 t-sql 性能
【发布时间】:2012-09-18 10:30:35
【问题描述】:

我继承了以下语句:

SELECT ISNULL((SELECT (-1)*SUM(CAST(ISNULL(NULLIF(TOTALMTDLCY,''),0) AS DECIMAL(20,5))) 
FROM TI),0) 

虽然我知道它想要做什么(防止空值并返回 0),但我觉得必须有一种更高效的方式来做到这一点?

原因是我有一个存储过程,它使用此语句 12 次从不同的表中获取值,用于 40,000 个客户 (480,000),然后为每个 (1.5M) 插入三个记录。

这需要大约 13 分钟才能完成 - 通过收集有关该过程的一些简单统计数据并将它们汇总,它表明虽然 12 条语句的实际时间为 00:00.015,但总时间约为 10 分钟。

所以,我的想法是,如果我可以加快这个过程,那么我可以加快我的存储过程?

【问题讨论】:

  • TOTALMTDLCY的数据类型是什么?
  • varchar(25) 不幸的是:(
  • ISNULL 和 NULLIF 不是您的性能问题的原因。为什么你认为正是这些功能是原因?
  • 这是一个永远不会允许高性能代码的设计缺陷。如果您需要数学函数的小数,如果您想要性能,它们必须存储为小数或数字。总是以错误的数据类型存储数据。此外,当你这样做时,你最终会得到非数字值 inteh 以及导致额外的问题。您需要修复数据库结构,然后您不需要浪费时间转换为数据应该存储的内容。
  • 如果您将其用作相关子查询(您发布的 sn-p 让我相信您是),那么您正在逐行运行,即使您修复了数据类型问题,性能会很差。相关子查询是最后的手段,当它们可以被替换时不应该使用。本质上,它们是具有所有固有性能问题的游标。

标签: sql-server performance tsql


【解决方案1】:

你不应该使用 varchar 来存储数值,它只会让你伤心 .将所有值从 varchar 转换为 decimal 成本很高。

像这样改变你的桌子

update TI set TOTALMTDLCY = null where TOTALMTDLCY = ''
alter table TI alter column TOTALMTDLCY DECIMAL(20,5) null

现在您可以毫无问题地选择

select isnull(-sum(TOTALMTDLCY), 0) from TI

【讨论】:

  • 抱歉,无法更改表...它从恐龙时代就已经存在,并且还有很多其他进程正在运行:(
  • 如果不能改表,就不能调脚本。你可以稍微修改一下脚本,但性能基本一样
【解决方案2】:

如果可行的话,你可以试试这个..

SELECT (-1) * SUM(ISNULL(CAST(TOTALMTDLCY AS DECIMAL(20,5)),0)) FROM TI WHERE TOTALMTDLCY <> ''

PS:我目前无法访问 SQL Sever,所以还没有验证它。

【讨论】:

    【解决方案3】:
    SELECT 
    ISNULL(
      -(SELECT SUM(CAST(TOTALMTDLCY as DECIMAL(20,5))) 
         FROM TI where TOTALMTDLCY<>'')
      ,0) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-11
      • 1970-01-01
      • 2011-07-23
      • 2017-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多