【问题标题】:How do I build effecient SQL filters?如何构建高效的 SQL 过滤器?
【发布时间】:2016-10-09 00:59:04
【问题描述】:

在参加了高级 T-SQL 性能/查询调优课程后,我记得我听过的一句话是,如果您将日期(时间)过滤器放在首位,您可以稍微加快一些查询。

例如:

WHERE
    RunDate = '12/1/2015' AND
    OtherFilters = etc...

但这真的只有在我为该表过滤的这些列上设置了索引时才算数吗?

所以要补充一点,我是否应该根据查询中引用的任何表的索引构建过滤器?这样我的第一个查询过滤器就基于我的索引?

例如:

WHERE
    ID > 1000 AND
    RunDate <= '1/1/206' AND
    OtherFilters = etc...

IDRunDate 是我的索引/主键的一部分。

【问题讨论】:

  • 希望你记错了,而不是有人真正教过。
  • 额外作业:继续学习covering index。请注意,SQL Server 2005 及更高版本支持included columns 以及复合索引。
  • 如果您对其他研究感兴趣,这里有几个相关主题。一旦数据库引擎构建了一个查询计划来执行一个查询,它可能会缓存它以便快速重用。 计划缓存可能会成为一件坏事。如果查询包含参数,则缓存计划可能会受到参数嗅探的影响,导致它对于不同的参数值远非最优。类似地,索引统计往往会随着时间而改变,缓存计划可能会变得低效。架构更改,例如如果不更新查询计划,添加索引可能不会带来好处。等等。 Ref.

标签: performance tsql sql-tuning


【解决方案1】:

WHERE 子句中过滤器的顺序无关紧要。只要您在字段上有索引,SQL Server 就知道如何使用您的过滤器。

假设您在 (ID, RunDt) 上有索引,并且在 WHERE 子句中同时有 IDRunDt。 SQL Server 首先过滤ID 上的数据,然后从该子集行中过滤RunDt

如果您有其他索引,这种情况可能会改变,这取决于您的数据的选择性。

另外,如果您在RunDt 上有clustered 索引,SQL 将首先过滤RunDt,然后是ID。

您无需担心 WHERE 子句中过滤器的顺序,只要您在索引定义中具有正确的列顺序即可。

【讨论】:

  • 过滤器不限于索引。优化器还将优化没有索引的列。
  • @Paparazzi 我不认为 FLICKER 的意图是暗示过滤器仅限于索引。我认为 FLICKER 是在说 SQL Server 知道如何优化您的过滤器,即使引用的列上有索引并且过滤器的顺序不同。
  • @Paparazzi,我不明白你的意思。你在谈论统计数据吗?
  • @Paparazzi 但要求优化器这样做会增加处理时间,对吧?因此,最有效的方法是创建涉及我过滤的大多数(如果不是全部)列的索引。
  • "只要字段上有索引,SQL Server 就知道如何使用您的过滤器。" SQL 必须知道如何在没有索引的情况下进行过滤,并且它还会优化这些过滤器。
【解决方案2】:

TSQL 只是一种逻辑表示

查询优化器将设置最有效的实际执行顺序
它有时会搞砸,但在大多数情况下它都在

如果您在 ID 上有一个集群 PK,那么这通常会先完成

似乎连 OP 都对这个问题感到困惑
只能回答所述问题

但这真的只有在我有这些索引的情况下才算 我为此表过滤的列?

  • where 中的顺序对于具有索引的列无关紧要

  • where 中的顺序对于没有索引的列无关紧要

  • where中的顺序无所谓

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多