sql server查询性能where子句

Posted

技术标签:

【中文标题】sql server查询性能where子句【英文标题】:sql server query performance where clause 【发布时间】:2012-02-13 17:02:59 【问题描述】:

我得到了一张有 10 000 行的表格。

declare @a table
(
  id bigint not null,
  nm varchar(100) not null,
  filter bigint
  primary key (id)
)

一个包含 4-5 个连接的选择需要 x 秒。如果添加 where 子句,现在需要 3x 秒。 where 子句:

filter = @filder or
filter is null

我在列上应用了一个非聚集索引,但性能只有 10%。

有什么建议吗?

编辑:添加过滤器列时会发生性能问题。所有连接都在主键上。

【问题讨论】:

用于连接的列是否是任何索引的一部分? 您在选择哪些字段?如果您有 4-5 个连接,这些键是否在连接的两侧都有索引? SELECT filter FROM @a WHERE ........ 的表现如何?如果您正在执行SELECT * 并因此拥有索引很可能根本没有帮助,因为查询优化器仍将扫描整个表(因为您在 SELECT 中要求 所有列 ) .... 只是一个提示,你可以将'@filter or filter is null'替换为isnull(@filder, filter) 尝试删除并重新创建索引。 【参考方案1】:

我对此有一些想法:

    您的联接很有可能是在 table.id 上加入的 - 这是一个主键并具有索引 - 宾果 - 高选择性(因为值是唯一的)。当它被索引时,优化器真的可以optimize 访问这个表,当它用于连接时。

    我不是 100% 确定,但是 - 要么您在 filter 上没有索引,要么它没有足够的选择性。如果您没有索引 - 优化器将使用表扫描。如果您确实有索引,但它的选择性不够,那么无论如何它都会使用表扫描。扫描很昂贵。

    即使您在filter 上有索引,优化器也不喜欢OR 谓词。基本上,当使用OR 时,优化器最终可能会使用索引扫描而不是索引查找。尝试改用这个:@filder = ISNULL(Filter, @filder as @sut13 建议。

所以要提高性能:如果您没有索引,请在 filter 上添加一个索引,并按照我的建议调整您的 where 子句以不使用 OR

还有:

您不应期望使用 where 过滤器的查询的性能等于或优于使用 4-5 个连接的查询。如果带有连接的查询更具选择性并更好地利用索引,那么它的性能会更好

【讨论】:

【参考方案2】:

过滤列上缺少索引(根据您在结构上描述的内容)很可能会导致表扫描。唯一可以确定的方法是查看查询的执行计划。这将告诉您优化器对查询做了什么,并且通常会为您提供足够的信息,以便您了解它为什么这样做以及您需要做些什么来修复它。

您可能需要在过滤器列上建立索引。但是,使用“OR filter IS NULL”可能会导致扫描,具体取决于数据中有多少空值。

如果您按照概述使用 ISNULL,不幸的是,这是列上的一个函数,并且可能(取决于使用的索引和 WHERE 子句中可用于初始过滤数据的其他列等)导致扫描而不是搜索。

【讨论】:

以上是关于sql server查询性能where子句的主要内容,如果未能解决你的问题,请参考以下文章

WHERE 子句中的 OR 会降低 sql 查询性能(sql server)

如何强制 SQL Server 在 WHERE 子句之前处理 CONTAINS 子句?

SQL Server:性能问题:WHERE 子句中的 OR 语句替换

使用有点奇怪的where子句的sql查询性能

WHERE 子句中的 SQL 查询子选择优化 (SQL Server)

SQL Server:IF .. ELSE 中的 Where 子句