如果包含或不包含列,则会影响查询性能,但奇怪的是,如果包含该列,则会影响正数(减少执行时间)。
查询包括对视图的一些连接,一些表和带有值的函数,如下一个:
SELECT
v1.field1, t2.field2
FROM
view v1 WITH (nolock)
INNER JOIN
table t1 WITH (nolock) ON v.field1 = t1.field1
INNER JOIN
table2 t2 WITH (nolock) ON t2.field2 = t1.field2
INNER JOIN
function1(@param) f1 ON f1.field3 = t2.field3
WHERE
(v.date1 = @param OR v.date2 = @param)
如果我在select
varchar(200) not null
列中包含视图的一部分(它没有在原始表或视图中编入索引,并且它不是一个约束条件),查询性能是X秒,但如果我不包括它,那么性能会提升到4X秒,这对于包含一个列来说有很大的不同;所以具有最佳性能的查询将如下:
SELECT
v1.field1, t2.field2, v1.fieldWhichAffectsPerformance
view v1 WITH (nolock)
INNER JOIN
table t1 WITH (nolock) ON v.field1 = t1.field1
INNER JOIN
table2 t2 WITH (nolock) ON t2.field2 = t1.field2
INNER JOIN
function1(@param) f1 ON f1.field3 = t2.field3
WHERE
(v.date1 = @param OR v.date2 = @param)
必须删除提高查询性能的列,但不会以负面方式影响实际性能。有什么想法吗?
编辑:正如我所建议的那样,审查了执行计划,没有列的查询运行额外的哈希匹配(左外连接)并使用索引扫描,这需要花费大量CPU而不是索引查找哪些是计划在包含列的查询中。如何在不影响性能的情况下删除列?任何想法?答案 0 :(得分:0)
优化器很复杂。没有查询计划,只有猜测。 您需要查看查询计划才能得到真正的答案。
一种可能性是处理顺序。 select
可以等同地写为:
SELECT t1.field1, t2.field2
因为on
条件指定两个表中的列相同。优化器我认识到or
阻止在视图上使用索引(这可能不适用)。因此,它不是扫描视图,而是决定扫描table1
,然后引入视图。
通过在select
中添加一个额外的列,您可以推动优化器扫描视图 - 这可能是更好的执行计划。
这都是假设的,但它提供了一种机制,说明观察时间的发生方式。