繁体   English   中英

sql server查询性能where子句

[英]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%。

有小费吗?

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

我对此有几点想法:

  1. 您的联接很可能在table.idtable.id -这是一个主键,并且具有索引table.id高选择性(因为值是唯一的)。 通过将其编入索引,优化器可以真正在联接中使用该表时optimize对该表的访问。

  2. 我不确定100%,但是-您在filter上没有索引,或者索引不够有选择性。 如果您没有索引-优化器将使用表扫描。 如果您确实有索引,但是索引的选择性不够,它将始终使用表扫描。 扫描很昂贵。

  3. 即使您在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM