【问题标题】:Database performance of view vs new table视图与新表的数据库性能
【发布时间】:2012-03-29 05:08:07
【问题描述】:

我正在使用一个性能较慢的 Oracle 数据库,因为在某些表上连接以获得结果。我正在考虑创建一个新表来存储其中一些数据,以便可以快速检索它而无需执行连接。另一种选择是为我正在执行的连接创建一个视图,然后始终在视图中查询数据。使用新表与创建视图之间的性能权衡是什么?我认为视图仍然需要运行连接,因此它不会提供与新表一样好的性能。

关于 Oracle 数据库视图的信息在这里: - http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_8004.htm - What is a View in Oracle?

根据以下回复进行澄清。查询大多已经优化,所以我不想做优化。更喜欢新表或物化视图,但想知道哪个可能更好。我对性能感兴趣。编写更多代码以使新表与旧表保持同步不是问题。我只会在对旧表进行修改的地方添加修改语句。如果物化视图比添加新表慢,我不想使用它。

区别在于数据的刷新对于物化视图还是对于新表更有效。对于新表,基本上我会在旧表有更新的地方添加更新语句。因此,当用户查询新表时,数据已经存在(无需进一步处理)。但是对于物化视图,如果视图仅在用户查询视图时自行刷新,那么这可能会更慢。

【问题讨论】:

  • View 根据查询显示数据。这样可以避免数据复制并节省您的存储空间,而不是创建新表。我认为对于性能问题,请查看查询优化。
  • 我认为你的意思是物化视图,不是吗?
  • 哦,需要看看区别,我刚开始使用oracle。我只使用简单的视图,比如CREATE VIEW
  • 您的问题是您有很多复杂的查询,这些查询都可以单独运行,但是当您组合它们时执行很糟糕?
  • 您的论点:“由于连接而导致性能下降”并不令人信服。通常,通过正确引入索引,连接作为索引嵌套循环执行。因此,没有根本原因为什么您的连接查询应该比简单查询慢得多(从具有单个表谓词的一个表中选择)。

标签: database oracle database-design


【解决方案1】:

视图只是一个存储查询,因此查询视图和针对基表发出相同查询之间的性能应该没有差异。

创建一个单独的表可能会提高查询的性能,但它违反了规范化,然后您必须编写代码来保持该表的同步。如果您需要查询返回正确的结果而不是近似结果,这意味着您的 DML 操作(插入、更新和删除)将变慢以处理保持数据同步的问题。如果这主要是一个报告数据库,这可能是一个适当的折衷方案,但在事务性能至关重要的 OLTP 环境中,这将不太合适。

如果您要创建一个表,我通常建议您改为创建一个materialized view。这具有表的性能优势,但 Oracle 负责保持同步,因此您不必为此编写大量自定义代码。

但是,首先将数据具体化并不是正确的解决方案,这一点并不明显。你确定你不只是缺少一些索引吗?

【讨论】:

  • 但是物化视图在复杂的查询中不能快速刷新,这会是个问题。如果他想在每个 DML 上完全刷新一个 MV,那么使用 MV 有什么好处?
  • @AmirPashazadeh - 好处是您不必编写、维护和调试一堆代码来尝试使物化数据与基础数据保持同步。如果您有一个复杂的查询,Oracle 无法为其创建快速可刷新的物化视图,那么您将难以开发代码以保持物化数据在事务上的一致性。
  • 同意,但我相信优化查询是首先要做的事情,大多数时候查询优化就是答案。
  • @AmirPashazadeh - 我同意优化查询可能是更好的答案。这就是为什么我首先在​​回答中包含了关于具体化数据是否是正确解决方案的问题。
  • 澄清。这主要是一个报告数据库(它用于对多条数据进行一些历史比较),而不是 OLTP 环境。查询大多已经优化,所以我不想做优化。更喜欢新表或物化视图,但想知道哪个可能更好。谢谢。
【解决方案2】:

视图只是查询的包装器,使用视图的性能与使用查询的性能相同(如果忽略查询解析开销)。

因此,如果您使用大量连接,则使用视图不会帮助您解决问题。但是在 Oracle 查询优化方面的大量经验之后,我可以给你一些注意事项:

  1. 尽可能使用子选择(在您的选择子句中)而不是加入;在某些情况下,无法做到这一点,或者这样做不好,例如:
    • 当您使用内部联接从结果集中删除一些记录时 -
    • 您希望对这些列设置一些条件
    • 您想对这些列进行排序。
  2. 可以使用union all 而不是union
  3. 在适当的时候使用coalesce,(甚至将它与子选择一起用作参数),
  4. 创建适当的索引(根据您的执行计划)
  5. 避免在联接和 where 子句中使用存储函数。

这些是我现在想到的事情。希望对您有所帮助。

【讨论】:

    【解决方案3】:

    materialized view 可能就是您要找的。常规的view 不作为表存在,它只是引用它所基于的表。但是,就像 Linutis 评论的那样,您应该首先尝试优化您的查询。您可能需要连接中涉及的列的索引,以及您正在使用的表上收集的统计信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      相关资源
      最近更新 更多