首页 > 解决方案 > 过滤 2 万行的视图需要 30 分钟

问题描述

我的问题是我有一个视图可以返回某一天的 20.000 行数据

select * from view
where date = X

但是当我为我需要的周边添加一个 where 子句时

select * from view 
where date = X and perimeter in ( 'A' , 'B' , 'C', 'D' )

结果或多或少有 10.000 行,但最多需要 30 分钟才能得到结果。

视图非常复杂,有几十个连接和聚合等

我该如何解决?

感谢您的帮助,我有任何问题,问我:)

** 更新:感谢您的回答。真正的查询相当复杂。这只是解释我的问题的一个例子。执行计划相当长且无用,因为无论我是否在边界列上使用过滤器,我都有完全相同的(100%)相同的执行计划(估计的和实际的)。但是后面的时间从我只过滤日期的 30 秒到我添加周边过滤器的 30 分钟。所以这一定意味着执行计划无论如何都是错误的。统计信息通常会在该表上更新。在我寻找它的表上的该列上没有索引。是否需要为视图添加一个?由于视图中的左连接,我们过滤的列被检索到**

标签: sqlsql-serverview

解决方案


首先问自己:

花这么多时间正常吗?

在某些情况下,当数据量大、语句复杂时,某些查询需要更多时间是正常的。

如果这不是你的情况,那么:

  • 我需要所有列吗?-为什么SELECT *,有时只选择需要的列可以优化视图执行
  • 我需要视图中使用的所有逻辑吗?- 如果视图如此复杂,请考虑是否有可能只获取您需要的语句(例如,创建具有更少逻辑、更少数据源、更少列的单独视图)
  • 查询是否使用了最佳索引 - 这是一个很大的话题,但您正在执行filtering,所以有可能使用适当的索引甚至过滤索引来优化查询?
  • 我可以提前过滤数据吗?- 有时您可以创建内联表值函数以提前执行过滤(该函数基本上是一个带参数的视图 - 想象将参数“X”传递给该函数,该函数将传递给现在返回的视图中引用的其他函数之前生成的行中只有 5% - 因此,您的子句中的某些值WHERE可能可以作为参数传递);
  • 我需要具体化这个观点吗?- 这是最后的手段,但您可以在视图上创建索引,以便像普通表一样具体化它并进一步优化性能(请注意,并非每个视图都可以被索引)

据我所见,许多开发人员正在使用遗留视图,这些视图是为解决过去的特定问题而创建的,而不是创建新视图。很多时候,这些观点的作用远远超过实际需要。


推荐阅读