当前位置: 首页 > 面试题库 >

WHERE-CASE子句子查询性能

谷梁裕
2023-03-14
问题内容

该问题可能特定于SQL Server。当我编写查询时,例如:

SELECT * FROM IndustryData WHERE Date='20131231'
AND ReportTypeID = CASE WHEN (fnQuarterDate('20131231')='20131231') THEN  1 
                        WHEN (fnQuarterDate('20131231')!='20131231') THEN  4
                        END;

是否对表的EACH行执行Case内的Case内的函数调用fnQuarterDate(或任何子查询)?

如果我预先在类似这样的变量中获取函数(或任何子查询)的值,会怎么样呢?

DECLARE @X INT
IF fnQuarterDate('20131231')='20131231'
SET @X=1 
ELSE
SET @X=0
SELECT * FROM IndustryData WHERE Date='20131231'
AND ReportTypeID = CASE WHEN (@X = 1) THEN  1 
                        WHEN (@X = 0) THEN  4
                        END;

我知道在MySQL中,如果WHERE子句中的IN(..)内有子查询,则对每一行都执行该子查询,我只想为SQL SERVER查找相同的子查询。

只需填充约3万行的表,然后发现时差:

Query1 = 70ms; 查询2 = 6毫秒。我认为这可以解释它,但仍然不知道其背后的实际事实。

如果不是一个UDF,而是一个简单的子查询,也会有什么区别吗?


问题答案:

我认为该解决方案在理论上可以帮助您提高性能,但是它也取决于标量函数的实际作用。我认为在这种情况下(我的猜测是将日期格式化为该季度的最后一天)确实可以忽略不计。

您可能需要阅读此页面,并附有建议的解决方法:

http://connect.microsoft.com/SQLServer/feedback/details/273443/the-scalar-
expression-function-would-speed-performance-while-keeping-the-benefits-of-
functions#

因为SQL Server必须在每一行上执行每个函数,所以使用任何函数都会产生游标,如性能下降。

在变通办法中,有一条评论指出

当我在连接列中使用标量UDF时,我遇到了同样的问题,其性能令人震惊。在我用包含UDF结果的临时表替换了UDF并将其用于join子句后,性能提高了几个数量级。MS团队应修复UDF以使其更可靠。

因此看来,是的,这可能会提高性能。

您的解决方案是正确的,但是我建议您考虑对SQL进行改进以使用ELSE,它对我来说看起来更干净:

AND ReportTypeID = CASE WHEN (@X = 1) THEN  1 
                    ELSE 4
                    END;


 类似资料:
  • 问题内容: 当表开始增长时,我担心WHERE子句中IN的性能。有没有人对这种查询有更好的策略?子查询返回的记录数比TradeLine表中的记录数增长得慢得多。TradeLine表本身以每天10个的速度增长。 谢谢你。 编辑:我使用了将子查询从WHERE移到FROM的想法。我对有助于此新查询的所有答案投了赞成票。 问题答案: 子句中的子查询不依赖于外部查询中的任何内容。您可以安全地将其移到子句中;一

  • 问题内容: 是否可以执行这样的mysql查询? 我需要在一般的“ where”子句中使用子查询的结果。 问题答案: 您可以将其包装在子查询中,如下所示:

  • 问题内容: 我最近才刚开始使用SQLAlchemy,但仍无法解决某些概念。 归结为基本元素,我有两个这样的表(通过Flask-SQLAlchemy): 我将如何查询用户列表及其最新帖子(不包括无帖子的用户)。如果我使用的是SQL,则可以执行以下操作: 因此,我确切地知道“期望的” SQL可以达到我想要的效果,但是不知道如何在SQLAlchemy中“正确地”表达它。 编辑:如果很重要,我使用的是SQ

  • 问题内容: 谁能给我一些关于如何将这种子查询放入提示?(我正在使用 JPA 2.0 - Hibernate 4.x ) -第二个选择将始终获得单个结果或null。 问题答案: 尝试类似以下示例的操作来创建子查询: 请注意,由于附近缺少IDE,因此该代码尚未经过测试。

  • 问题内容: 我有一个查询: 我只想从表中选择周期和年份等于的行: 我知道最简单的方法是使用连接,但是问题是-在应用程序中,我只能在后面添加一个子句 因此,解决方案应该是: 那可能吗? 编辑: 结果应与以下相同: 问题答案: 您可以为条件使用多个列: 但是戈登的解决方案可能更快。