我有一个复杂的查询,我需要在随后的查询中使用(实际上UPDATE语句)。 我一直在使用一个CTE和临时表都尝试。 使用CTE的性能是可怕VS临时表的方法。 它像15秒VS毫秒。 为了简化,而不是在我简单地选择从*它的后续查询加入CTE /临时表的测试。 在这种情况下,他们执行相同。
我已在执行计划找了这两种方法都与在随后的查询中的连接,然后简单地选择*。 通过这样的简单选择查询计划大致相同,但在随后的连接选择的查询计划都没有。 特别用于创建和填充临时表的查询计划的部分保持不变,而用于创建和填充的CTE查询计划部分急剧变化时,它在一个查询随后用于与联接。
我的问题是为什么由它是如何随后使用而临时表是不是该CTE变化的创作和人口的查询计划。 此外,在什么情况下会随后的CTE产生比一个临时表中更好的表现?
*注意:我已经使用了一个表变量,以及和它相媲美的临时表的方法。
谢谢
你问一个复杂的问题,所以你得到一个复杂的答案:这取决于。 (I恨响应)。
说真的,但是,它与优化器如何选择一个数据计划(你知道的话)做的; 临时表或变量是像在执行计划将执行与第一填充该结构相关联的操作,并且然后使用该结构在随后的操作的永久结构。 甲CTE不是一个临时表; 不计算使用CTE,直到它被用来通过后续操作,并让使用影响的计划是如何优化。
CTE的是为可重用性和维护问题,不一定是性能落实; 然而,在很多情况下(如递归),他们将执行比传统的编码方式更好。
CTE
只是用于查询的别名。
它可能(也可能不会),它的每次使用时必须重新运行。
有没有干净的方式来强制CTE
在物化SQL Server
(如Oracle的/*+ MATERIALIZE */
),而你所要做的肮脏的把戏是这样的:
CTE
如果只需要一个评估计划使用可以提高性能(如HASH JOIN
, MERGE JOIN
等)。
在这些情况下,哈希表将直接从内置CTE
在使用临时表将需要评估, CTE
,拉动结果存入临时表,并再次读取该临时表。
我发现,通常重复CTE就没有得到性能的提升。
因此,举例来说,如果你使用一个CTE来填充一个表,然后在同一CTE加入到在随后的查询中,没有任何好处。 不幸的是,热膨胀系数不快照和他们硬是要反复在两个单独的语句来使用,所以他们往往是两次评估。
取而代之的CTE的,我经常使用内联TVFs(其中可能包含的CTE),它允许适当的再利用,并且并不比CTE的更好或更坏在我的SP。
此外,我还发现,如果第一步改变了统计,例如,对于第二个步骤的执行计划始终是不准确的,因为在运行任何步骤之前,其被评估的执行计划可不好。
在这种情况下,我看着手动保存中间结果,确保他们得到适当的索引和分裂的过程分为多个SP并添加WITH重新编译以确保以后的SP有有利于它们究竟要操作的数据计划上。
我试图从大表滤波器选择简单的创建CTE然后3次subqueried它。
在那之后做临时表一样。
其结果是70%耗时CTE -30%耗时为临时表。 因此,临时表是该解决方案更好。
我不认为CTE使得一个临时表,只有选定的查询,但3次作出选择,以一张大桌子。