SQL中的临时表

SQL中的临时表,sql,Sql,我需要知道,将复杂查询分解为多个部分并创建临时表(在最后删除)是否是标准做法。?在OLAP应用程序中,这不应该是一个很大的问题,但在OLTP中,因为速度很重要,所以它是可以避免的?在OLTP处理过程中,我唯一使用临时表的时间是在处理一批需要分析/连接的数据时,并最终对其执行数据更改操作(插入/更新/删除)。我将使用临时表来提高a)速度,但更重要的是,b)因为正常的选择/更新或选择/删除逻辑太复杂,或者不能在一个事务语句中完成 例如,找到满足某些条件的10万用户,将其插入存档表中,然后将其删除 我

我需要知道,将复杂查询分解为多个部分并创建临时表(在最后删除)是否是标准做法。?在OLAP应用程序中,这不应该是一个很大的问题,但在OLTP中,因为速度很重要,所以它是可以避免的?

在OLTP处理过程中,我唯一使用临时表的时间是在处理一批需要分析/连接的数据时,并最终对其执行数据更改操作(插入/更新/删除)。我将使用临时表来提高a)速度,但更重要的是,b)因为正常的选择/更新或选择/删除逻辑太复杂,或者不能在一个事务语句中完成

例如,找到满足某些条件的10万用户,将其插入存档表中,然后将其删除


我不建议在大多数情况下对正常的select语句使用临时表。通过适当的索引、更好的sql连接/提示和/或更改数据结构以匹配数据访问路径,您几乎总能获得更好的性能。

您问题中的关键词是“分解”。通常不鼓励使用临时表和其他策略,并发现它们会导致整体绩效降低。如果中间表有助于最快得到答案,那么优化器完全能够使用它们。您很少能够通过使用自己的策略强制优化器来帮助它

建议使用哪些索引也是一样的


当您看到这种情况时,几乎总是有人需要做更多的工作来优化查询语句。

对于由DBMS优化的简单查询,临时表通常是一个坏主意,因为它们会引入开销

但是有时候,您的DBMS将很难优化复杂的查询。此时,您至少有5个选项:

  • 更改模式或索引,使优化器更容易选择更好的查询计划
  • 调整SQL,让DBMS选择您想要的索引、连接策略等,并解决DBMS优化器中已知和未知的错误
  • 使用“提示”让DBMS选择所需的索引、连接策略等
  • 获取所需的计划,并使用“保存的计划”强制DBMS使用该计划
  • 使用临时表(或表变量等)将复杂查询分解为更简单的中间查询
  • 对于任何特定的查询,没有硬性规定哪一个选项是最好的。我已经使用了上述所有策略。当我不拥有模式时,我倾向于选择临时表方法,因此我无法更改它,当我不想依赖提示、查询优化或保存的计划时(通常是因为我不想让自己暴露在以后对基础模式所做的更改中)

    请记住,使用临时表分解查询每次都会给您带来次优性能。但它通常是可预测的次优。使用临时表的最坏情况并不像DBMS为单个大型查询选择错误的计划那样糟糕。这种情况出人意料地经常发生,尤其是面对底层模式的变化、DBMS版本的变化、开发与生产的差异等等

    就我个人而言,我发现如果一个查询达到某种复杂程度,我必须竭尽全力让DBMS做我想做的事情,如果我觉得应用程序的可维护性有风险,那么如果我不能更改模式或索引,我通常会使用分解表和临时表


    当然,从理论上讲,您不应该在OLTP数据库上运行昂贵、复杂的查询,但在实践中,大多数应用程序从来都不是“纯”OLTP——在任何OLTP项目中都有一些复杂、难以优化的查询

    在oltp系统中,如果处理是在线系统的一部分(即不是批处理),则我无法回忆起是否使用过临时表。使用某种过程逻辑通常是一种方法,例如Oracle中的PL/Sql等等

    在OLAP中,临时表非常常见,通常将数据加载到一个表中,对其进行转换并将结果保存到另一个表中,并且根据处理的不同有许多转换步骤

    我甚至想说,如果您有一个oltp系统,并且需要使用一个临时表,那么就会出现一些错误,修改您的设计,或者使用过程逻辑。在OLAP中,临时表非常常见


    hth

    您是否将“复杂”查询分解,以使业务逻辑更易于应用,或更具可读性,而不是试图提高性能。。。或者反过来呢?我发现当CTE被实现时,我对临时表的需求几乎消失了。