【问题标题】:SELECT with WHERE drops performanceSELECT with WHERE 会降低性能
【发布时间】:2021-12-05 17:46:17
【问题描述】:

在我的应用程序中,我使用类似的查询

SELECT column1, column2 
FROM table 
WHERE myDate >= date1 AND myDate <= date2

我的应用程序崩溃并返回超时异常。我复制查询并在 SSMS 中运行它。结果窗格显示约 40 秒的执行时间。然后我删除查询的WHERE 部分并运行。这一次,返回的行立即出现在结果表中,尽管查询继续打印更多行(表中有 500 万行)。

我的问题是:WHERE 子句如何影响查询性能?

注意:我不会更改应用程序中的CommandTimeOut 属性。默认离开。

【问题讨论】:

  • 您很可能需要在该列上建立索引,否则 MSSQL 必须搜索数据库中的每条记录才能找到相关数据。您可以检查查询计划以查看查询类型,请参阅stackoverflow.com/a/7359705/507793 了解如何获取查询计划。
  • 默认超时是多少? 30 秒?强烈建议将其更改为至少几分钟。显然,也可以在该列上添加一个索引,但无论性能如何,您的所有查询都不太可能在超时内执行
  • 请通过https分享查询计划;//berntozar.com/pastetheplan。还请在您的问题中添加表和索引定义。否则我们无法回答这个问题
  • @PhilCoulson 如果索引良好,没有理由在几秒钟内无法返回数百万行
  • @Charlieface 是的,没错,但我的建议更笼统。数据集可能要大得多,而且可能并不总是拥有修改索引的权限(许多数据分析师的职业生涯都是从只读权限开始的)。或者可能存在没有故意为更快插入进行优化的巨大表的索引。对我来说,30 秒对于查询超时来说似乎太短了

标签: sql-server select where-clause sqlperformance timeoutexception


【解决方案1】:

如果没有 WHERE 子句,SQL Server 被告知只开始返回行,所以它就是这样做的,从它可以有效找到的第一行开始(可能是聚集索引中的“第一”行,或者覆盖非聚集索引)。

当你用 where 子句限制它时,SQL Server 首先必须去查找那些行。这就是您所等待的,因为您在 myDate(或 date1/date2,我不确定是列还是变量)上没有索引,它需要检查每一行。

另一种看待它的方式是考虑电话簿,这是一个过时的类比,但可以完成工作。如果没有 WHERE 子句,就好像你要我读出书中所有的名字和数字。如果您添加一个索引不支持的 WHERE 子句,例如读出每个名字为“John”的人的姓名和号码,我将需要更长的时间才能开始返回行,因为我不能甚至开始,直到我找到第一个约翰。

或者稍微不同的类比是考虑书中的索引。如果你要求我读出所有被索引的术语的页码,我可以从索引中做到这一点,从头开始读到最后。如果您要求我读出所有不在索引中的术语的所有页码,或特定的未索引术语(如“the”),甚至是索引的所有页码包含字母 a 的术语,我会更难过。

【讨论】:

    猜你喜欢
    • 2017-11-27
    • 2012-07-06
    • 2016-02-25
    • 1970-01-01
    • 2015-07-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多