【问题标题】:Optimizing queries for the particular table优化特定表的查询
【发布时间】:2015-03-26 07:33:35
【问题描述】:

我有一张桌子,我正在寻找一种方法来提高它的性能。下面是要执行的查询列表。

dbo.CustomersSmallOrders
(
    ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    CustomerName VARCHAR(MAX) NOT NULL,
    OrderDate DATETIME NOT NULL,
    Quantity INT NOT NULL,
    Amount DECIMAL(15,2) NOT NULL,
    AvailableAmount DECIMAL(15,2) NOT NULL,
    Type TINYINT NOT NULL,
    Status TINYINT NOT NULL
)

您能帮我重写下面的查询并向表中添加索引以提高其性能吗?

SELECT *
FROM CustomersSmallOrders
WHERE Left(CustomerName, 4) = 'Levis'

SELECT *
FROM CustomersSmallOrders
WHERE DateDiff(month, OrderDate, GetDate()) >= 30

SELECT *
FROM CustomersSmallOrders
WHERE Quantity * 2 < 3400

SELECT 
    SUM(CASE 
            WHEN Type = 2 AND STATUS IN (0, 1, 2) THEN Amount 
            ELSE 0 
        END)
    ,SUM(CASE 
             WHEN Type = 1 AND STATUS IN (0, 1) THEN Amount 
             ELSE 0 
         END)
    ,SUM(CASE 
             WHEN Type = 2 AND STATUS IN (0, 1) THEN Amount - AvailableAmount 
             ELSE 0 
         END)
FROM CustomersSmallOrders
WHERE STATUS IN (0, 1, 2)

【问题讨论】:

  • 这是作业吗?这些查询似乎被设计成不可告人的。
  • 嘿,这永远不会带来任何东西! SELECT * FROM CustomersSmallOrders WHERE Left(CustomerName, 4) = 'Levis',你要将 5 个字符与 4 个字符进行比较 :)
  • 不是作业。这是我的经理检查我们是否了解同事每天所做的最新情况的方式,因此如果有人不在,就会有人代替他们。我觉得验证我们技能的方式很烦人。上次测试是基于开关和控制器。
  • @EvaldasBuinauskas 是的,我也这么认为,但我想咨询专家。
  • 因此,要优化@EvaldasBuinauskas 指出的那个,您可以使用SELECT TOP 0 * FROM CustomersSmallOrders,该计划根本不会访问该表。

标签: sql-server indexing query-optimization query-performance query-tuning


【解决方案1】:

查询改进:

正如 Martin Smith 所说,第一个查询可以转换为

SELECT TOP 0 * FROM CustomersSmallOrders

因为矛盾。

曾经

WHERE Left(CustomerName, 5) = 'Levis'

然后将条件更改为

WHERE CustomerName LIKE 'Levis%'

将保留查询 sargable 并允许使用索引。

可以通过更改条件并在 OrderDate 上添加索引来改进第二个查询:

SELECT *
FROM CustomersSmallOrders
WHERE OrderDate <= DATEADD(Mounth, -30, GetDate()) 

第三个(在数量上添加索引):

SELECT *
FROM CustomersSmallOrders
WHERE Quantity < 1700

第 4 次 - 在 STATUS 上添加一个索引,其中还包含 Type、Amount 和 AvailableAmount(虽然我不明白他为什么要两次 Amount。我认为这可能是一个错误,他只想要 1 列输出):

SELECT 
SUM(CASE 
        WHEN Type = 2 THEN Amount 
        ELSE 0 
    END)
,SUM(CASE 
         WHEN Type = 1 AND STATUS IN (0, 1) THEN Amount 
         ELSE 0 
     END)
,SUM(CASE 
         WHEN Type = 2 AND STATUS IN (0, 1) THEN Amount - AvailableAmount 
         ELSE 0 
     END)
FROM CustomersSmallOrders
WHERE STATUS IN (0, 1, 2)

【讨论】:

  • 非常感谢 Zohar!
  • 如果你能接受这个答案,我会原谅你拼错我的名字:-)
  • 没问题,无论如何我都会原谅你...感谢@MartinSmith 改进我的答案:-)
猜你喜欢
  • 2010-09-13
  • 2017-03-06
  • 1970-01-01
  • 1970-01-01
  • 2021-01-30
  • 2015-01-14
  • 1970-01-01
  • 2021-09-04
  • 2019-02-25
相关资源
最近更新 更多