我有一张有10000行的桌子。
declare @a table
(
id bigint not null,
nm varchar(100) not null,
filter bigint
primary key (id)
)使用4-5个join的select需要x秒。如果添加where子句,现在需要3x秒。where子句:
filter = @filder or
filter is null我在列上应用了非聚集索引,但性能仅提高了10%。
有什么建议吗?
编辑:添加过滤器列时出现性能问题。所有联接都在主键上。
发布于 2012-02-14 02:10:43
我对此有几点想法:
table.id上连接的-这是一个主键,并且具有索引-宾果-高选择性(因为值是唯一的)。有了它的索引,优化器可以真正的optimize访问这个表,当它被用于连接。filter上,或者它没有足够的选择性。如果没有索引,优化器将使用表扫描。如果您确实有一个索引,但它没有足够的选择性,那么无论如何它都会使用表扫描。扫描是expensive.filter上有一个索引,那么优化器就不喜欢OR谓词。基本上,当使用OR时,优化器可能最终使用索引扫描而不是索引查找。尝试使用这个:按照@sut13的建议使用@filder = ISNULL(Filter, @filder。因此,要提高性能:如果没有索引,请在filter上添加一个索引,并按照我的建议调整where子句,使其不使用OR。
另外:
您不应该期望使用where筛选器的查询的性能与使用4-5个连接的查询相同或更好。如果包含连接的查询具有更高的选择性并更好地利用索引,那么它的性能将会更好
发布于 2012-02-14 02:59:41
筛选器列上缺少索引(基于您在结构上所描述的内容)很可能导致表扫描。确定的唯一方法是查看查询的执行计划。这将告诉您优化器正在对查询做什么,并且通常会给您足够的信息,这样您就可以理解它为什么要这样做,以及您需要做些什么来修复它。
可能,您需要过滤器列上的索引。但是,使用'OR filter IS NULL‘可能会导致扫描,这取决于数据中有多少空值。
不幸的是,如果您按照前面所述使用ISNULL,那么这是列上的一个函数,并且可能会(这取决于所使用的索引以及WHERE子句中可用于初始过滤数据的其他列,等等)。导致扫描而不是搜索。
https://stackoverflow.com/questions/9264638
复制相似问题