我最近在某处读过调整SQL查询的方法之一是,如果它有太多的连接,那么用较少的表做一个连接并将结果缓存到临时表中,然后执行其余的查询加入表
我的问题是它如何改善性能,因为你加入相同数量的表(只是不在一起)?
注意:我同意这是通用声明;我最近在一篇文章中读到了它。我会改写它。在什么条件下将结果存储到临时表帮助?
答案 0 :(得分:6)
您投资Oracle等产品的原因之一是它们在其引擎的优化器部分中进行的开发工作。它已经不断改进超过20年,并且通常,通过适当的表和索引统计数据,很难正确地将其用于访问您的数据。
如果我将您的问题解释为每次查询执行时通过构建临时表来提高实时数据查询的性能,我会说在大多数情况下都不会。在其他情况下,不是构建临时表,而是花时间使用Oracle的相对较新的WITH子句来构造查询,该子句将在优化器有意义的情况下动态地处理实现数据的子集。
如果您的问题是关于在物化视图,数据集市或数据仓库方式中对数据进行非规范化,那么这可以显着提高查询性能,代价是访问当前信息状态(因为非规范化表总是在外面日期)。这种改进通常是因为RDBMS引擎对查询的物理访问工作较少,因为您已经完成了一次构建非规范化结构。
答案 1 :(得分:1)
如果多次运行此查询而不重建临时表,这将提高性能。第一个查询可能会在正常时间运行,但后续查询将避免获取临时表的数据。但是,该表中的数据将变得陈旧 - 在构建之后的更新将不会显示在以后的查询中。
对于不一定是最新的查询,这可能是可以接受的 - 例如,统计报告查询通常可以使用一天的数据。
作为替代方案,许多数据库支持物化视图(或索引视图),这些视图实际上是临时表,无论何时执行更新,它都会自动保持最新。
您还可以使用更新时的触发器或通过存储过程执行更新来手动重现此效果。这种方法导致数据库非常脆弱,并且通常容易出错,因此我建议不要使用它。
答案 2 :(得分:1)
这在很大程度上取决于您的具体情况 - 这种变化可能会伤害或改善表现。这没有一般规则; 你遇到问题的查询是什么?
它可以提高性能,因为结果可能是一个更小的表,更容易查询和加入;查询优化器可能会自动执行此操作,但在某些情况下会出错。这是一种手动完成优化器工作的方法。
答案 3 :(得分:0)
我认为这个“规则”已经出现,因为当涉及到许多表时,数据库引擎的行为变得很难预测 - 每个额外的表都会增加执行查询的可能方式的数量。
理论上,可以准确地跟踪Oracle优化器如何做出决策,并使用统计信息,提示和计划为其提供正确工作所需的信息。
实际上,这个过程似乎经常落在开发人员/ DBA的差距上 - 无论是在培训方面还是在访问所需工具方面。
临时表方法的缺点是,当资源发生变化时,您已阻止数据库使用“更好”的优化(即数据库服务器现在具有8Gb的内存,因此最快的方法是将所有表完全加载到内存,但临时表方法已强制写回磁盘)。
答案 4 :(得分:0)
我永远不会考虑使用临时表来提高单个查询的性能。 (我假设您正在讨论实际的表,而不是具体化的视图。)根据我的经验,Oracle可以在至少99.9%的时间内连接数十个表而没有问题。 (如果您有最新的统计数据。)
对于那些看起来不太理想的罕见情况,您应该首先尝试在Oracle提供的系统内工作。我看到的大多数性能问题都是因为某人没有以合乎逻辑的方式做某事,或者他们不了解现有的功能。例如,使用相同的表两次而不是使用分析。如果Oracle仍在使用糟糕的解释计划,那么您应该考虑使用提示,或者添加ROWNUM来阻止Oracle重写某些子查询。
如果临时表有帮助,Oracle将为您完成所有操作。有时你可以在解释计划中看到像“SYS_TEMP ......”这样的对象。