Las vistas en línea le permiten seleccionar de una subconsulta como si fuera una tabla diferente:
SELECT
*
FROM /* Selecting from a query instead of table */
(
SELECT
c1
FROM
t1
WHERE
c1 > 0
) a
WHERE
a.c1 < 50;
He visto esto referido al uso de diferentes términos: vistas en línea, cláusula WITH, CTE y tablas derivadas. Para mí parece que son diferentes sintaxis específica del proveedor para la misma cosa.
¿Es esta una suposición errónea? ¿Hay alguna diferencia técnica / de rendimiento entre estos?
oracle
cte
derived-tables
Kshitiz Sharma
fuente
fuente

WITH...). Puede volver a escribir cada tabla derivada como CTE, pero tal vez no al revés (por ejemplo CTE recursiva o el uso de los CTE varias veces)Respuestas:
Existen algunas diferencias importantes entre las vistas en línea (tablas derivadas) y la cláusula WITH (CTE) en Oracle. Algunos de ellos son bastante universales, es decir, son aplicables a otros RDBMS.
WITHse puede usar para crear subconsultas recursivas, vista en línea -no (por lo que sé, lo mismo es para todos los RDBMS que admiten CTE)WITHcláusula es más probable que se ejecute físicamente primero; En muchos casos, elegir entreWITHy la vista en línea hace que el optimizador elija diferentes planes de ejecución (supongo que es específico del proveedor, tal vez incluso de la versión).WITHpuede materializarse como una tabla temporal (no sé si algún otro proveedor pero Oracle admite esta función).WITHpuede hacer referencia a la subconsulta en varias veces, en otras subconsultas y en la consulta principal (verdadero para la mayoría de los RDBMS).fuente
LATERALse use.Otras respuestas cubren las diferencias de sintaxis bastante bien, así que no voy a entrar en eso. En cambio, esta respuesta solo cubrirá el rendimiento en Oracle.
El optimizador de Oracle puede optar por materializar los resultados de un CTE en una tabla temporal interna. Utiliza una heurística para hacer esto en lugar de la optimización basada en costos. La heurística es algo así como "Materializar el CTE si no es una expresión trivial y se hace referencia al CTE más de una vez en la consulta". Hay algunas consultas para las cuales la materialización mejorará el rendimiento. Hay algunas consultas para las cuales la materialización degradará drásticamente el rendimiento. El siguiente ejemplo es un poco artificial pero ilustra bien el punto:
Primero cree una tabla con una clave primaria que contenga enteros del 1 al 10000:
Considere la siguiente consulta que usa dos tablas derivadas:
Podemos ver esta consulta y determinar rápidamente que no devolverá ninguna fila. Oracle debería poder usar el índice para determinar eso también. En mi máquina, la consulta finaliza casi instantáneamente con el siguiente plan:
No me gusta repetirme, así que intentemos la misma consulta con un CTE:
Aquí está el plan:
Ese es un plan realmente malo. En lugar de usar el índice, Oracle materializa 10000 X 10000 = 100000000 filas en una tabla temporal solo para eventualmente devolver 0 filas. El costo de este plan es de alrededor de 6 M, que es mucho más alto que la otra consulta. La consulta tardó 68 segundos en finalizar en mi máquina.
Tenga en cuenta que la consulta podría haber fallado si no hay suficiente memoria o espacio libre en el espacio de tabla temporal.
Puedo usar la
INLINEsugerencia no documentada para evitar que el optimizador materialice el CTE:Esa consulta puede usar el índice y finaliza casi al instante. El costo de la consulta es el mismo que antes, 11. Entonces, para la segunda consulta, la heurística utilizada por Oracle resultó en que eligiera una consulta con un costo estimado de 6 M en lugar de una consulta con un costo estimado de 11.
fuente
Para SQL Server,
WITH CTEespecifica el conjunto de resultados con nombre temporal, pero solo se requiere para el primeroCTE. es decirPero esto no es una subconsulta o una subconsulta correlacionada. Hay cosas que puede hacer con un CTE que no puede hacer con una subconsulta en SQL Server, como actualizar las Tablas a las que se hace referencia en un CTE. Aquí hay un ejemplo de actualización de una tabla con un CTE.
Una subconsulta sería algo así como
O una subconsulta correlacionada es lo que ha proporcionado en su OP si tuviera que hacer referencia / unirse / limitar sus resultados según a.c1.
Por lo tanto, definitivamente no son lo mismo, aunque en muchos casos podría usar uno o más de estos métodos para lograr el mismo resultado. Solo depende de cuál sea el resultado final.
fuente
La principal diferencia entre la
withcláusula y una subconsulta en Oracle es que puede hacer referencia a una consulta dentro de la cláusula varias veces. A continuación, puede hacer algunas optimizaciones con él, como convertirlo en una tabla temporal con unamaterializesugerencia. También puede hacer consultas recursivas con ella haciendo referencia a sí misma dentro de unawithcláusula. No puede hacer eso con una vista en línea.Se puede encontrar más información aquí y aquí .
fuente
MATERIALIZEresp.INLINEpor lo contrariomaterializesugerencia es una opción válida. A veces necesitaba especificarlo al optimizar consultas muy complejas donde sabía que materializar el CTE beneficiaría el plan de ejecución.Debe tener cuidado con los CTE en el servidor SQL, no solo con Oracle, hay casos en los que las consultas funcionan mucho peor cuando se usan CTE en comparación con las subconsultas, la aplicación cruzada, etc.
Como siempre, es importante probar cualquier consulta en varias condiciones de carga para determinar cuál funciona mejor.
Al igual que @scsimon con Oracle, a veces el servidor MS SQL no hace lo que espera con respecto al uso del índice.
Si va a usar los mismos datos más de una vez, los CTE pueden ser más útiles, si solo los usa una vez, a menudo una subconsulta es más rápida en grandes conjuntos de datos.
por ejemplo, seleccione * de (mi subconsulta) unirse a otra cosa ...
fuente