A CTE o no a CTE


Habiendo estado atascado con SQL2000 durante demasiado tiempo, realmente no he tenido mucha exposición a Expresiones de Tabla Comunes.

Las respuestas que he dado aquí (#4025380) y aquí (#4018793) han ido en contra del flujo en que no usaron un CTE.

Aprecio que para la recursividad son las beez kneez, y hay algunas consultas que pueden simplificarse mucho por su uso, pero ¿en qué momento su uso es simplemente frívolo? Tienen un gran rendimiento beneficio sobre una subconsulta o un join? ¿Realmente simplifican el código y lo hacen más fácil de mantener?

En resumen, cuándo es una buena práctica usar un CTE sobre una sintaxis 'menor'.

Author: Community, 2010-10-28

4 answers

Generalmente debe usar un CTE sobre una subconsulta normal si:

  • Su consulta requiere recursión (como usted señaló)
  • La subconsulta es grande o compleja
  • La consulta contenedora es grande o compleja
  • La subconsulta se repite (o al menos varias subconsultas se pueden simplificar realizando diferentes operaciones simples en una subconsulta común)

En resumen, sí hacen que las consultas sean más legibles cuando se usan bien.

 22
Author: KeithS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-27 20:53:21

Personalmente, una vez que me sentí cómodo usándolos, creo que producen un código más limpio y legible. Como ejemplo, compare su respuesta con la mía en #4018793. Esencialmente hicimos lo mismo; usé un CTE y tú no.

Su respuesta sin 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

Mi respuesta con 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
 18
Author: Joe Stefanelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:33:35

Son azúcar sintáctica, con la excepción de las consultas jerárquicas/recursivas.

Sin embargo, no todo lo que se puede hacer recursivamente debería ser - la generación de fechas a través de CTE recursivo era apenas mejor que un cursor the el truco de la tabla de NÚMEROS escaló mucho mejor.

 3
Author: OMG Ponies,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-27 20:54:04

CTE produce un resultado más rápido en un escenario recursivo. El resultado de CTE se utiliza repetidamente para obtener el resultset final. Así que ya que ha tomado su cláusula where o subconsulta en CTE, definitivamente va a mostrar una mejora en el rendimiento.
Referencia: http://msdn.microsoft.com/en-us/library/ms190766 (v = sql.105).aspx

Solo una nota, en muchos escenarios, las tablas temporales también dan un mejor rendimiento que CTE, por lo que también debe probar las tablas temporales.
Referencia : http://social.msdn.microsoft.com/Forums/en/transactsql/thread/d040d19d-016e-4a21-bf44-a0359fb3c7fb

 2
Author: NG.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-21 14:50:01