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 语句替换