【问题标题】:Are duplicate math operations reran in case expressions?是否在 case 表达式中重新运行重复的数学运算?
【发布时间】:2023-01-27 20:54:40
【问题描述】:

在下面的示例中,sql 执行是否会“缓存”fuel + cost 的结果?或者数学可能会运行三次?这不是一个真实的用例,我只是想出了这个例子来模仿更现实的需求。


select case when shipFuelSurcharge + shipCost > 0
                        then 'over'
                    when shipFuelSurcharge + shipCost < 0
                        then 'under'
                    when shipFuelSurcharge + shipCost = 0
                        then 'equals'
            end as ExampleMathCase
    from shippment

【问题讨论】:

  • 更现实的需求是什么?数据库不只是执行 SQL 查询,它们还将它们转换为使用特定索引、扫描策略、数据缓存等的执行计划。即使语法不同,逻辑上等效的查询通常也会产生相同的执行计划。 IO 也比简单的加法更昂贵,所以性能这个CASE 条款不应该有可检测的影响
  • 要求与示例非常相似,每条记录,我需要评估一个数学方程,如果结果高于给定数字,则选择该数学的结果+另一个变量,否则只返回数学。本质上,我想弄清楚将这个逻辑从 sql 中提取出来是否会更好......如果它会更有效率
  • 发布实际查询,不要描述它。 IO 比 3 个加法要贵得多——贵几个数量级。如果您真的需要查看发生了什么,请检查实际的执行计划。会有一个计算值的Compute Scalar节点。不管那个表情是什么,它可能没有影响性能 - 同样,仅读取一行比 ADD 操作慢 100-1000 倍。通过网络发送结果也是如此。
  • 肯定有一些表达式会导致数据引擎重新运行所述表达式。像 CASE (SELECT TOP (1) a FROM dbo.SomeTable) WHEN 1 THEN (SELECT TOP (1) a FROM dbo.SomeTable) END 这样的(写得不好的)表达式可能会导致子查询运行两次,并且因为没有 ORDER BY 它甚至可能意味着 CASE 表达式返回一个不同于 1NULL 的值.
  • Panagiotis,我想显示的查询在一个更大的查询中,很难在这里显示。我无法在我的公司运行查询计划。但我想你已经回答了我的问题。我感谢讨论。

标签: sql sql-server


【解决方案1】:

实际上,这笔款项将被执行三次。

也许您可以在 SubSelect 中计算数据 shipFuelSurcharge + shipCost,这样您就可以“预加载”它并且可以根据需要多次使用它而无需重新计算它。

像这样的东西

SELECT CASE WHEN ValuesSUM > 0 
        THEN 'over' 
    WHEN ValuesSUM < 0 
        THEN 'under' 
    WHEN ValuesSUM = 0 
        THEN 'equals' 
END ExampleMathCase FROM (
    SELECT ShipNumber,shipFuelSurcharge + shipCost ValuesSUM FROM shippment) a

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 2014-07-31
    • 2013-11-28
    • 1970-01-01
    相关资源
    最近更新 更多