【问题标题】:Improving performance on a view with a LOT of joins [closed]通过大量连接提高视图的性能[关闭]
【发布时间】:2009-12-17 21:11:06
【问题描述】:

我有一个使用 11 个外连接和两个内连接来创建数据的视图。这导致超过 800 万行。当我在桌子上进行计数(*)时,大约需要 5 分钟才能运行。我不知道如何提高这张表的性能。有人对从哪里开始有任何建议吗?所有正在加入的列上似乎都有索引(虽然有些是复合的,但不确定这是否会有所不同......)

任何帮助表示赞赏。

【问题讨论】:

  • 您查看过估计/实际执行计划吗?如果您在某处缺少索引,他们会告诉您
  • 我看过了。没有占用大量时间的表扫描。有很多“哈希匹配”加起来性能很差,但是哈希匹配只有在索引使用正确的情况下才会执行?
  • 我发现一个非常有用的技巧是将复杂查询分解为子查询,例如如果您有一个包含 11 个连接的查询 - 对于通常无法同时考虑超过 4 个连接的优化器来说,这是一项艰巨的工作。我会尝试使用 4 个连接保持外部查询将其他连接移动到子查询。在一些情况下帮助了我。

标签: sql-server join performance left-join


【解决方案1】:

这是一个困难的问题,对于复杂的视图,您还可能与针对视图的查询进行交互,因此保证合理的性能将非常困难。视图中的外连接(尤其是复杂的)也容易给查询优化器带来麻烦。

一种选择是实现视图(在 SQL Server 上称为“索引视图”)。但是,您可能需要监视更新性能以检查它是否不会产生太多开销。此外,物化视图中的外部连接可能会妨碍实时刷新。如果您需要这个,那么您可能需要将视图重新实现为非规范化表并使用触发器维护数据。

另一种可能性是检查视图是否可以拆分为两个或三个更简单的视图,可能实现部分但不是全部视图。以这种方式具体化一些视图并从系统中获得性能可能会更容易。

【讨论】:

  • 我曾考虑创建索引视图,但据我了解,您无法在使用任何类型外连接的视图上执行此操作。我错了吗?
  • 没错。您可能能够具体化视图的一部分,然后在其之上构建一个视图。或者,您可以将视图重新实现为由一组触发器维护的表。
  • 是的,我认为这是我必须采取的方法。
  • 您知道这需要多少空间吗?让这种观点持续存在并不是一个好主意。
【解决方案2】:

你的基本前提是错误的。 拥有一个返回 800 万行的视图并不是一个好主意,因为实际上你不能用这么多的数据做任何事情。 由于所有这些连接,5 分钟对于 800 万个 count() 来说听起来不错。

您要做的是考虑您的业务问题并编写一个较小的查询/视图。

【讨论】:

    【解决方案3】:

    您可以考虑以下几点:

    1. 非规范化。通过对数据结构进行非规范化来减少所需的连接数量
    2. 分区。您可以从大表中分区数据吗?例如一个大表,如果分区成多个较小的表,性能会更好。从 SQL 2005 开始的企业版对分区有很好的支持,请参阅here。如果您开始进入 10s/100s 数百万行的领域,会考虑这一点
    3. 索引管理/统计。是否所有索引都进行了碎片整理?统计数据是最新的吗?

    【讨论】:

      【解决方案4】:

      运行 sql profiler/index 调整向导。有时它提出的索引建议并不立即有意义,但结果却带来了出色的性能优势

      【讨论】:

      • 我不知道 Profiler 提出了建议。你是说查询分析器吗?
      • 抱歉,实际执行建议的工具是“Sql Server 索引调整向导”。该工具将分析器跟踪文件作为输入:-)
      【解决方案5】:

      也许您尝试(外部)加入的某些表是不相交的?如果是这样,请考虑创建存储过程而不是视图并创建如下内容:

      select ... into #set1 from T1 left join T2 left join... where ...

      select ... into #set2 from T3 left join T4 left join... where ...

      ...

      select ... from #set1 left join #set2 left join ...

      这样,您可以避免处理大量数据。当您进行外连接时,优化器通常无法在查询的解析树中向下移动选择(如果这样做,您将不会得到您可能想要的带有空值的行)

      当然,您不能通过加入存储过程来创建查询。这只是您可以使用的基本概念。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-06
        • 2013-11-25
        • 2012-06-16
        相关资源
        最近更新 更多