问题描述
|
我需要知道将复杂的查询分解为多个部分并创建临时表,然后将它们放到最后是否是标准做法。在OLAP应用程序中,这不应该是一个大问题,但是在OLTP中,因为速度很重要,可以避免吗?
解决方法
对于由DBMS很好优化的简单查询,临时表通常是个坏主意,因为它们会带来开销。
但是有时候您的DBMS很难优化复杂的查询。到那时,您至少有5个选择:
更改架构或索引,以使优化程序更容易选择更好的查询计划
调整SQL以使DBMS选择所需的索引,联接策略等,并解决DBMS优化器中的已知错误和未知错误。
使用“提示”来使DBMS选择所需的索引,联接策略等。
获得所需的计划,并使用“已保存的计划”来强制DBMS使用它。
使用临时表(或表变量等)将复杂的查询分解为更简单的中间查询
关于哪个选项最适合任何特定查询,没有严格的规定。我已经使用了所有上述策略。当我不拥有架构时,我倾向于选择临时表方法,因此我无法更改它,并且当我不想依赖提示或查询调整或保存的计划时(通常是因为我不这样做) \不想让自己暴露于稍后进行的基础架构更改)。
请记住,使用临时表分解查询将使您每次的性能都不理想。但这通常是次优的。使用临时表的最坏情况并不像您的DBMS为单个大型查询选择错误的计划那样糟糕。这种情况经常出乎意料地发生,尤其是在基础架构发生更改,DBMS版本更改,开发与生产差异等情况下。
我个人发现,如果查询达到某种程度的复杂性,我必须向后弯腰以使DBMS能够执行我想要的事情,并且如果我觉得应用程序的可维护性受到威胁,那么我将经常如果我无法更改架构或索引,请使用分解表和临时表。
当然,从理论上讲,您不应该在OLTP数据库上运行昂贵,复杂的查询,但实际上,大多数应用程序从来都不是“纯”的OLTP-总是有一些复杂的,难以优化的在任何OLTP项目中查询。
, 您问题中的关键词是“分解”。通常不建议使用临时表和其他策略,这会导致总体性能降低。如果中间表对于最快速地找到答案很有用,则它可以完美地使用中间表。您很少会通过自己的策略来强制优化器。
建议使用哪些索引也是一样。
当您看到这种情况时,几乎总是有人需要做更多的工作来完善他们的查询语句。
, 在OLTP处理期间,我唯一使用过临时表的时间是当我处理一批需要分析/加入的数据,并最终对其进行数据更改操作(插入/更新/删除)时。我将使用临时表来实现a)速度,但更重要的是b),因为常规的选择/更新或选择/删除逻辑要么太复杂,要么无法在一个事务语句中完成。
例如,找到10万个满足某些条件的用户,然后将其插入存档表,然后将其删除。
我不建议在大多数情况下对常规select语句使用临时表。通过适当的索引编制,更好的sql连接/提示和/或更改数据结构以匹配数据访问路径,几乎总是可以得到更好的性能。
, 在oltp系统中,如果处理是在线系统的一部分(即非批处理),那么我将永远无法使用临时表进行回忆。使用某种程序逻辑通常是可行的方法-例如Oracle中的PL / Sql等。
在OLAP中,临时表非常普遍,通常将数据加载到表中,对其进行转换并将结果保存在另一个表中,并且根据处理需要执行许多转换步骤。
我要说的是,如果您有oltp系统,并且需要使用临时表,那么可能是不正确的,修改设计或使用过程逻辑。在OLAP中,临时表非常常见。
高度