[英]sql server query performance where clause
我有一张有1万行的桌子。
declare @a table
(
id bigint not null,
nm varchar(100) not null,
filter bigint
primary key (id)
)
一个选择(具有4-5个联接)需要x秒。 如果添加了where子句,则现在需要3秒钟。 where子句:
filter = @filder or
filter is null
我在列上应用了非聚集索引,但是性能却只有10%。
有小费吗?
编辑:添加过滤器列时会发生性能问题。 所有联接都在主键上。
我对此有几点想法:
您的联接很可能在table.id
上table.id
-这是一个主键,并且具有索引table.id
高选择性(因为值是唯一的)。 通过将其编入索引,优化器可以真正在联接中使用该表时optimize
对该表的访问。
我不确定100%,但是-您在filter
上没有索引,或者索引不够有选择性。 如果您没有索引-优化器将使用表扫描。 如果您确实有索引,但是索引的选择性不够,它将始终使用表扫描。 扫描很昂贵。
即使您在filter
上有索引,优化器也不喜欢OR
谓词。 基本上,当使用OR
,优化器可能最终会使用索引扫描而不是索引查找。 尝试改用此方法: @filder = ISNULL(Filter, @filder
@filder如@ sut13建议。
因此,为了提高性能:如果没有索引,请在filter
上添加一个索引,并按照我的建议调整where子句以不使用OR
。
也:
您不应该期望带有where
过滤器的查询的性能等于或优于具有4-5个联接的查询。 如果使用联接的查询更具选择性,并且更好地利用了索引,那么执行起来会更好
过滤器列上缺少索引(基于您在结构上描述的内容)的情况很可能导致表扫描。 确保的唯一方法是查看查询的执行计划。 这将告诉您优化程序对查询的处理方式,通常可以为您提供足够的信息,以便您了解执行此操作的原因以及修复该查询所需要执行的操作。
可能您需要在过滤器列上建立索引。 但是,使用“ OR过滤器IS NULL”可能仍会导致扫描,具体取决于数据中有多少个null值。
不幸的是,如果使用概述中的ISNULL,则这是该列上的函数,并且可能(取决于所使用的索引和WHERE子句中可用于初始过滤数据的其他列等)导致扫描并不是寻求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.