【问题标题】:How to get a record depending of an other record without CTE and UNION如何在没有 CTE 和 UNION 的情况下根据其他记录获取记录
【发布时间】:2018-03-29 18:25:15
【问题描述】:

我需要从我的成本表中提取一条记录,并且只有在没有找到具有特定值的记录时才需要一个通用记录。我有那个可以工作的简化查询,基本上可以做我想做的事。

WITH BaseCost AS (
    SELECT *
    FROM dbo.Table1 
    WHERE Val1 = 'SomeValue'
          AND Val2 = 'OtherValue')
SELECT TOP 1 *
FROM (
    SELECT 1 seq ,*
    FROM BaseCost WHERE Val3 = 'MyValue'
    UNION
    SELECT 2 seq ,*
    FROM BaseCost WHERE Val3 = '*')QRY
ORDER BY QRY.seq

我想知道,有没有比创建 CTE、UNION 记录只取第一个更好的方法来实现这一点?这个查询会经常运行,我希望它尽可能快。

【问题讨论】:

  • 因为你只取一行UNION ALL会快一点。
  • 您可以愉快地使用UNION ALL 而不是UNION,因为不需要过滤掉重复项。
  • Remove Select *(只选择您需要的字段),无论您在做什么,这都是一个好习惯。
  • 为什么不只是SELECT TOP 1 <cols> FROM dbo.Table1 WHERE Val1 = 'SomeValue' AND Val2 = 'OtherValue' AND Val3 IN ('MyValue', '*') ORDER BY CASE WHEN Val3 = 'MyValue' THEN 1 WHEN Val3 = '*' THEN 2 END;?它的速度将取决于您是否投资了正确的索引来满足查询。
  • @lad2025,我没想到,但这是合乎逻辑的。在我的开发环境中,它没有什么不同,我会在 prod 中尝试。

标签: sql-server performance common-table-expression


【解决方案1】:

有了所有的建议,这就是我的 200K 记录表上更快的方法(现在不是那么多,但每天都在变大)

WITH BaseCost AS (
    SELECT Val1, Val2, Val3, OtherVal
    FROM dbo.Table1 
    WHERE Val1 = 'SomeValue'
          AND Val2 = 'OtherValue'
          AND Val3 IN ('MyValue', '*'))
SELECT TOP 1 Val1, Val2, Val3, OtherVal
FROM (
    SELECT 1 seq ,Val1, Val2, Val3, OtherVal
    FROM BaseCost WHERE Val3 = 'MyValue'
    UNION ALL
    SELECT 2 seq ,Val1, Val2, Val3, OtherVal
    FROM BaseCost WHERE Val3 = '*')QRY
ORDER BY QRY.seq

我真的很喜欢ORDER BY CASE WHEN 的想法,但它比实际查询慢,因为我需要快速执行,即使它更具可读性我也不能使用它。

【讨论】:

  • 您是否尝试将 CTE 写入临时表以查看它是否可以提高性能?
  • 刚试了一下,比 ORDER BY CASE WHEN 慢了一点
  • 将其写入表变量怎么样?
  • 我要做的工作的执行计划基本一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 2015-06-18
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 2021-11-26
  • 2012-04-18
相关资源
最近更新 更多