As visualizações embutidas permitem que você selecione de uma subconsulta como se fosse uma tabela diferente:
SELECT
*
FROM /* Selecting from a query instead of table */
(
SELECT
c1
FROM
t1
WHERE
c1 > 0
) a
WHERE
a.c1 < 50;
Eu já vi isso mencionado usando termos diferentes: visualizações em linha, cláusula WITH, CTE e tabelas derivadas. Para mim, parece que eles são sintaxe específica de fornecedor diferente para a mesma coisa.
Esta é uma suposição errada? Existem diferenças técnicas / de desempenho entre elas?
oracle
cte
derived-tables
Kshitiz Sharma
fonte
fonte
WITH...
). Você pode reescrever cada tabela derivada como uma CTE, mas talvez não o contrário (por exemplo recursiva CTE ou usando os CTE várias vezes)Respostas:
Existem algumas diferenças importantes entre as visualizações embutidas (tabelas derivadas) e a cláusula WITH (CTE) no Oracle. Alguns deles são bastante universais, ou seja, são aplicáveis a outros RDBMS.
WITH
pode ser usado para criar subconsultas recursivas, exibição em linha - não (até onde eu sei o mesmo é para todos os RDBMS que suportam CTE)WITH
É provável que a subconsulta na cláusula seja fisicamente executada primeiro; em muitos casos, escolher entreWITH
e a visualização embutida faz com que o otimizador escolha diferentes planos de execução (acho que é específico do fornecedor, talvez até da versão).WITH
pode ser materializada como uma tabela temporária (não sei se existe outro fornecedor, mas o Oracle suporta esse recurso).WITH
pode ser referenciada várias vezes, em outras subconsultas e na consulta principal (verdadeira para a maioria dos RDBMS).fonte
LATERAL
seja usada.Outras respostas cobrem muito bem as diferenças de sintaxe, portanto não vou entrar nisso. Em vez disso, essa resposta cobrirá apenas o desempenho no Oracle.
O otimizador Oracle pode optar por materializar os resultados de um CTE em uma tabela temporária interna. Ele usa uma heurística para fazer isso, em vez de otimização baseada em custos. A heurística é algo como "Materialize o CTE se não for uma expressão trivial e o CTE for referenciado mais de uma vez na consulta". Existem algumas consultas para as quais a materialização melhorará o desempenho. Existem algumas consultas para as quais a materialização prejudicará drasticamente o desempenho. O exemplo a seguir é um pouco artificial, mas ilustra bem o ponto:
Primeiro, crie uma tabela com uma chave primária que contenha números inteiros de 1 a 10000:
Considere a seguinte consulta que usa duas tabelas derivadas:
Podemos analisar esta consulta e determinar rapidamente que ela não retornará nenhuma linha. A Oracle deve poder usar o índice para determinar isso também. Na minha máquina, a consulta termina quase instantaneamente com o seguinte plano:
Eu não gosto de me repetir, então vamos tentar a mesma consulta com um CTE:
Aqui está o plano:
Esse é um plano muito ruim. Em vez de usar o índice, o Oracle materializa 10000 X 10000 = 100000000 linhas em uma tabela temporária apenas para retornar 0 linhas. O custo deste plano é de cerca de 6 M, o que é muito mais alto que a outra consulta. A consulta levou 68 segundos para terminar na minha máquina.
Observe que a consulta pode ter falhado se não houver memória suficiente ou espaço livre no espaço de tabela temporário.
Posso usar a
INLINE
dica não documentada para impedir o otimizador de materializar o CTE:Essa consulta é capaz de usar o índice e termina quase instantaneamente. O custo da consulta é o mesmo de antes, 11. Portanto, para a segunda consulta, a heurística usada pelo Oracle resultou na escolha de uma consulta com um custo estimado de 6 M em vez de uma consulta com um custo estimado de 11.
fonte
Para o SQL Server,
WITH CTE
especifica o conjunto de resultados nomeado temporário, mas é necessário apenas para o primeiroCTE
. ieMas isso não é uma subconsulta ou subconsulta correlacionada. Há coisas que você pode fazer com um CTE e o que não pode fazer com uma subconsulta no SQL Server, como atualizar as Tabelas referenciadas em um CTE. Aqui está um exemplo de atualização de uma tabela com um CTE.
Uma subconsulta seria algo como
Ou uma subconsulta correlacionada é o que você forneceu no seu OP se você referenciar / ingressar / limitar seus resultados com base em a.c1.
Portanto, eles definitivamente não são a mesma coisa, embora em muitos casos você possa usar um ou mais desses métodos para obter o mesmo resultado. Depende apenas do resultado final.
fonte
A principal diferença entre
with
cláusula e uma subconsulta no Oracle é que você pode fazer referência a uma consulta dentro da cláusula várias vezes. Em seguida, você pode fazer algumas otimizações como transformá-lo em uma tabela temporária usando amaterialize
dica. Você também pode fazer consultas recursivas fazendo referência a si mesma dentro de umawith
cláusula. Você não pode fazer isso com uma exibição embutida.Mais informações podem ser encontradas aqui e aqui .
fonte
MATERIALIZE
resp.INLINE
pelo contrário.materialize
dica é a opção válida. Às vezes, eu precisava especificá-lo ao otimizar consultas muito complexas, onde sabia que materializar o CTE beneficiaria o plano de execução.Você precisa ter cuidado com os CTEs no SQL Server e não apenas com a Oracle, há casos em que as consultas apresentam desempenho muito pior ao usar CTEs em comparação com subconsultas, aplicação cruzada etc.
Como sempre, é importante testar qualquer consulta sob várias condições de carga para determinar qual delas funciona melhor.
Semelhante ao @scsimon da Oracle, às vezes o MS SQL Server não faz o que você espera em relação ao uso do índice.
Se você usar os mesmos dados mais de uma vez, as CTEs poderão ser mais úteis; se você estiver usando apenas uma vez, geralmente uma subconsulta é mais rápida em grandes conjuntos de dados.
por exemplo, selecione * de (minha subconsulta) junte-se a outra coisa ...
fonte