首页 > 解决方案 > 如何让这条 SQL 行更高效?(分区依据时的情况)

问题描述

我有一个看起来像这样的 SQL 行

,SUM(Unit_Retail) OVER (PARTITION BY CASE WHEN @LocalDetailLevel = 'master' THEN Master_Item WHEN @LocalDetailLevel = 'size' THEN Item_Number WHEN @LocalDetailLevel = 'color' THEN CONCAT(Item_Number, Color_Code) END) AS Sum_Unit_Retail

它需要一个数字并将其相加,但重要的部分是分区。用户可以指定他想要的详细程度。

问题是,它需要很长时间才能运行。

我有很多这样的行,涉及零售、商品成本、版税等。

当我将其更改为简单版本时

,SUM(Unit_Retail) OVER (PARTITION BY Item_Number) AS Sum_Unit_Retail

现在整个查询在 5 秒对 40 秒内运行。

有什么办法可以让这条线更有效率吗?或者我应该改为进行三个单独的查询,首先检查参数是什么,然后根据它编写完整的查询?谁能给我一个关于如何做到这一点的骨架?我不确定语法。

喜欢

CASE WHEN @LocalDetailLevel = 'master' THEN 
BEGIN
...
END
CASE WHEN @LocalDetailLevel = 'size' THEN 
BEGIN
...
END
CASE WHEN @LocalDetailLevel = 'color'
BEGIN
...

这是正确的方法吗?或者这个问题有更好的解决方案吗?

标签: sqlsql-server

解决方案


为了我们的帮助,我们需要您提供一些东西。从这篇关于获取慢查询帮助的博客开始。我们需要的一件大事是通过 PasteThePlan.com 的执行计划

您可能遇到的一个问题是Parameter Sniffing。这是执行计划真正有助于了解您的查询在哪里遇到性能障碍的地方。

关于问题的最后一部分,您在其中创建了一个新问题......

CASE 是一个表达式,因此不用于控制逻辑流。

CASE 可用于任何允许有效表达式的语句或子句。例如,您可以在 SELECT、UPDATE、DELETE 和 SET 等语句中以及在 select_list、IN、WHERE、ORDER BY 和 HAVING 等子句中使用 CASE

对于您的问题,您将使用IF...ELSE.

语法非常相似...

IF @LocalDetailLevel = 'master' 
BEGIN
...
END

IF @LocalDetailLevel = 'size'
BEGIN
...
END

推荐阅读