CTE或CTE

时间:2010-10-27 20:47:38

标签: sql-server performance common-table-expression maintainability

长期以来,我一直坚持使用SQL2000,但我并没有真正接触过Common Table Expressions。

我给出的答案here (#4025380)here (#4018793)违反了流程,因为他们没有使用CTE。

我很感激,对于递归它们是beez kneez,并且有一些查询可以通过它们的使用大大简化,但在什么时候它们的使用只是轻浮?与子查询或联接相比,它们是否具有很好的性能优势?他们真的简化了代码并使其更易于维护吗?

简而言之,何时使用CTE而不是'较小'的语法是好的做法。

4 个答案:

答案 0 :(得分:23)

如果符合以下条件,通常应在正常子查询上使用CTE:

  • 您的查询需要递归(如您所述)
  • 子查询很大或很复杂
  • 包含的查询是大型还是复杂的
  • 重复子查询(或者通过对公共子查询执行不同的简单操作,可以简化至少几个子查询)

简而言之,是的,在使用得当时,它们确实使查询更具可读性。

答案 1 :(得分:19)

就个人而言,一旦我习惯使用它们,我认为它们可以生成更清晰,更易读的代码。例如,在#4018793上将您的答案与我的答案进行比较。我们基本上做了同样的事情;我使用过CTE但你没有。

没有CTE的答案:

SELECT
    course,
    section,
    grade,
    gradeCount
FROM
    table
INNER JOIN
    (SELECT
        grade,
        Max(gradeCount) as MaxGradeCount
    FROM
        table
    ) MaxGrades
    ON  table.grade = MaxGrades.grade
        AND table.gradeCount = MaxGrades.MaxGradeCount
ORDER BY 
    table.grade

我对CTE的回答:

;with cteMaxGradeCount as (
    select 
        grade, 
        max(gradeCount) as MaxGradeCount
    from @Test
    group by grade
)
select 
    t.course, 
    t.SECTION, 
    t.grade, 
    t.gradeCount
from cteMaxGradeCount c
inner join @Test t
    on  c.grade = t.grade
        and c.MaxGradeCount = t.gradeCount
order by t.grade

答案 2 :(得分:3)

它们是语法糖,除了分层/递归查询。

然而,并非所有可递归完成的事情都应该是 - 通过递归CTE生成日期几乎不比光标好 - NUMBERS表技巧缩放得更好。

答案 3 :(得分:2)

CTE在递归方案中产生更快的结果。 CTE的结果被重复用于获得最终结果集。因此,既然您已经在CTE中使用了where子句或子查询,那么它肯定会显示性能提升 参考:http://msdn.microsoft.com/en-us/library/ms190766(v=sql.105).aspx

请注意,在许多情况下,临时表也提供了比CTE更好的性能,所以你也应该试试临时表。
参考:http://social.msdn.microsoft.com/Forums/en/transactsql/thread/d040d19d-016e-4a21-bf44-a0359fb3c7fb