Uma visualização é mais rápida que uma simples consulta?

357

É um

select *  from myView

mais rápido que a própria consulta para criar a visualização (para obter o mesmo resultado definido):

select * from ([query to create same resultSet as myView])

?

Não está totalmente claro para mim se a exibição usa algum tipo de cache, tornando-a mais rápida em comparação com uma consulta simples.

JohnIdol
fonte
7
Não tenho certeza sobre uma exibição, mas as exibições aninhadas são um inferno de desempenho total.
Muflix 12/02

Respostas:

678

Sim , as visualizações podem ter um índice clusterizado atribuído e, quando o fazem, armazenam resultados temporários que podem acelerar as consultas resultantes.

Atualização: Pelo menos três pessoas votaram em mim nessa. Com todo o respeito, acho que eles estão errados; A documentação da própria Microsoft deixa muito claro que o Views pode melhorar o desempenho.

Primeiro, as visualizações simples são expandidas e, portanto, não contribuem diretamente para as melhorias de desempenho - isso é verdade. No entanto, as exibições indexadas podem melhorar drasticamente o desempenho.

Deixe-me ir diretamente para a documentação:

Depois que um índice clusterizado exclusivo é criado na visualização, o conjunto de resultados da visualização é materializado imediatamente e persistido no armazenamento físico no banco de dados, economizando a sobrecarga de executar essa operação dispendiosa no tempo de execução.

Segundo, essas visualizações indexadas podem funcionar mesmo quando não são diretamente referenciadas por outra consulta, pois o otimizador as utilizará no lugar de uma referência de tabela quando apropriado.

Mais uma vez, a documentação:

A exibição indexada pode ser usada na execução de uma consulta de duas maneiras. A consulta pode fazer referência diretamente à visualização indexada ou, o mais importante, o otimizador de consulta pode selecionar a visualização se determinar que a visualização pode ser substituída por alguma ou por toda a consulta no plano de consulta de menor custo. No segundo caso, a exibição indexada é usada em vez das tabelas subjacentes e de seus índices comuns. A visualização não precisa ser referenciada na consulta para o otimizador de consulta usá-lo durante a execução da consulta. Isso permite que os aplicativos existentes se beneficiem das visualizações indexadas criadas recentemente sem alterar esses aplicativos.

Esta documentação, bem como gráficos demonstrando melhorias de desempenho, pode ser encontrada aqui .

Atualização 2: a resposta foi criticada com base no fato de que é o "índice" que fornece a vantagem de desempenho, não a "Visualização". No entanto, isso é facilmente refutado.

Digamos que somos uma empresa de software em um país pequeno; Vou usar a Lituânia como exemplo. Vendemos software em todo o mundo e mantemos nossos registros em um banco de dados do SQL Server. Temos muito sucesso e, em alguns anos, temos mais de 1.000.000 de registros. No entanto, muitas vezes precisamos relatar vendas para fins fiscais e descobrimos que vendemos apenas 100 cópias de nosso software em nosso país. Ao criar uma exibição indexada apenas dos registros lituanos, mantemos os registros necessários em um cache indexado, conforme descrito na documentação da MS. Quando geramos nossos relatórios de vendas da Lituânia em 2008, nossa consulta pesquisará um índice com profundidade de apenas 7 (Log2 (100) com algumas folhas não utilizadas). Se fizéssemos o mesmo sem o VIEW e apenas contássemos um índice na tabela, teríamos que percorrer uma árvore de índices com uma profundidade de pesquisa de 21!

Claramente, o próprio View nos proporcionaria uma vantagem de desempenho (3x) sobre o simples uso do índice sozinho. Tentei usar um exemplo do mundo real, mas você observará que uma simples lista de vendas da Lituânia nos daria uma vantagem ainda maior.

Observe que estou apenas usando uma árvore b reta para o meu exemplo. Embora eu tenha quase certeza de que o SQL Server usa alguma variante de uma árvore b, não conheço os detalhes. No entanto, o argumento é válido.

Atualização 3: Surgiu a pergunta sobre se uma exibição indexada usa apenas um índice colocado na tabela subjacente. Ou seja, parafraseando: "uma exibição indexada é apenas o equivalente a um índice padrão e não oferece nada de novo ou exclusivo a uma exibição". Se isso fosse verdade, é claro, a análise acima estaria incorreta! Deixe-me fornecer uma citação da documentação da Microsoft que demonstra por que acho que essa crítica não é válida ou verdadeira:

Usar índices para melhorar o desempenho da consulta não é um conceito novo; no entanto, as visualizações indexadas fornecem benefícios adicionais de desempenho que não podem ser alcançados usando índices padrão.

Juntamente com a citação acima, referente à persistência de dados no armazenamento físico e outras informações na documentação sobre como os índices são criados no Views, acho seguro dizer que um Modo de Exibição Indexado não é apenas um SQL Select em cache que usa um índice definido na tabela principal. Assim, continuo apoiando esta resposta.

Mark Brittingham
fonte
28
Sim, as exibições indexadas podem melhorar drasticamente o desempenho. Mas as visualizações indexadas não são apenas "visualizações" e, de um modo geral, a "visualização" normal não é mais rápida que as consultas associadas.
BradC
10
@Charles - não importa se é o índice, o fato de que uma visão pode alavancar o índice e uma consulta matéria não pode é suficiente
annakata
193
/ aplaudir @ Marcos para estar firme e racionalmente discutir um presente para fora
annakata
17
Oh, cara, eu recebi 8 votos negativos neste! Estou surpreso que as pessoas votassem tão rapidamente, sem pelo menos ter a coragem de Charles para argumentar.
Mark Brittingham
8
Como uma tabela pode ter apenas um índice clusterdee e você PODE criar um índice clusterizado separado em uma exibição (uma vez que os campos no índice clusterizado são mantidos independentemente nas páginas de índice), isso é um truque (trabalho-resposta?) Que permite que você obtenha DOIS índices agrupados em uma tabela.
22330 Charles Bretana
50

De um modo geral, não. As visualizações são usadas principalmente por conveniência e segurança e não produzem (por si mesmas) nenhum benefício de velocidade.

Dito isto, o SQL Server 2000 e versões posteriores têm um recurso chamado Exibições Indexadas que podem melhorar bastante o desempenho, com algumas ressalvas:

  1. Nem toda visualização pode ser transformada em uma visualização indexada; eles têm que seguir um conjunto específico de diretrizes , que (entre outras restrições) significa que você não pode incluir elementos de consulta comuns, como COUNT, MIN, MAX, ou TOP.
  2. As visualizações indexadas usam espaço físico no banco de dados, assim como os índices em uma tabela.

Este artigo descreve benefícios e limitações adicionais de visualizações indexadas :

Você pode…

  • A definição de visualização pode fazer referência a uma ou mais tabelas no mesmo banco de dados.
  • Depois que o índice clusterizado exclusivo é criado, índices não clusterizados adicionais podem ser criados na visualização.
  • Você pode atualizar os dados nas tabelas subjacentes - incluindo inserções, atualizações, exclusões e até truncados.

Você não pode ...

  • A definição de visualização não pode fazer referência a outras visualizações ou tabelas em outros bancos de dados.
  • Ele não pode conter COUNT, MIN, MAX, TOP, junções externas ou algumas outras palavras-chave ou elementos.
  • Você não pode modificar as tabelas e colunas subjacentes. A visualização é criada com a opção WITH SCHEMABINDING.
  • Você nem sempre pode prever o que o otimizador de consulta fará. Se você estiver usando o Enterprise Edition, ele considerará automaticamente o índice clusterizado exclusivo como uma opção para uma consulta - mas se encontrar um índice "melhor", ele será usado. Você pode forçar o otimizador a usar o índice através da dica WITH NOEXPAND - mas tenha cuidado ao usar qualquer dica.
BradC
fonte
3
discordo totalmente ... a leitura de uma visão permite que o SQL seja reescrito .. e geralmente é MAIS RÁPIDO ler de uma visão (do que de um despejo da visão).
Aaron Kempf
@AaronKempf, eu adoraria ver alguma referência sobre isso, essa não foi a minha experiência. Quando procuro "visualizar SQL reescrito", todos os resultados que obtiveram referem-se ao Oracle, não ao SQL Server, por exemplo, docs.oracle.com/cd/E14072_01/server.112/e10810/qrbasic.htm
BradC
Eu estava apenas fazendo alguns testes de referência ontem, fiquei impressionado .. basicamente, se eu der um despejo de uma visualização (em uma tabela), qualquer consulta que eu execute é MAIS LENTA .. porque a maioria das consultas passa pela visualização como manteiga e é reescrita pelo otimizador de consultas .. Pelo menos é o que eu assumo. Em breve, tentarei escrever uma entrada de blog, o benchmarking era algo bastante fascinante. Basicamente, as visualizações ajudam tremendamente o desempenho.
Aaron Kempf 10/01
@AaronKempf Não tenho certeza se esse é o mesmo cenário da pergunta original (que é sobre uma consulta versus colocar essa consulta idêntica em uma exibição). De qualquer forma, não vejo como materializar uma exibição em uma tabela a tornaria MAIS LENTA (é exatamente isso que faz uma exibição indexada), a menos que sua nova tabela não tenha bons índices.
BradC
11
Brad; Eu escrevi uma postagem de blog muito ruim sobre como as visualizações estão me poupando 99% do meu desempenho nessa situação. Estou pensando em escrever alguns outros artigos, mas sei que preciso colocar MUITO mais detalhes nisso. Você se importa de dar uma olhada nisso e me dizer o que acha da minha descrição? Sei que não fará mais sentido (até que eu publique 2-3 outros artigos) .. mas estou loucamente apaixonada por opiniões, e estou há muito tempo! accessadp.com/2013/01/22/do-views-increase-performance
Aaron Kempf
14

No SQL Server, pelo menos, os planos de consulta são armazenados no cache do plano para visualizações e consultas SQL comuns, com base em parâmetros de consulta / exibição. Para ambos, eles são descartados do cache quando não são utilizados por um período suficientemente longo e o espaço é necessário para alguma outra consulta recém-enviada. Depois disso, se a mesma consulta for emitida, ela será recompilada e o plano será colocado novamente no cache. Portanto, não, não há diferença, pois você está reutilizando a mesma consulta SQL e a mesma exibição com a mesma frequência.

Obviamente, em geral, uma visão, por sua própria natureza (que alguém pensou que deveria ser usada com frequência suficiente para torná-la uma visão), geralmente tem mais chances de ser "reutilizada" do que qualquer instrução SQL arbitrária.

Charles Bretana
fonte
14

Edição: Eu estava errado, e você deve ver Marks responder acima.

Não posso falar por experiência própria com o SQL Server , mas para a maioria dos bancos de dados a resposta seria não. O único benefício potencial que você obtém, em termos de desempenho, ao usar uma exibição é que ela pode criar alguns caminhos de acesso com base na consulta. Mas o principal motivo para usar uma exibição é simplificar uma consulta ou padronizar uma maneira de acessar alguns dados em uma tabela. De um modo geral, você não terá um benefício de desempenho. Eu posso estar errado, no entanto.

Gostaria de apresentar um exemplo moderadamente mais complicado e cronometrar você mesmo para ver.

Ryan Guill
fonte
11
Outra razão para a vista é auxiliar de controle de acesso em modelos baseados papel
annakata
11
Você está errado sobre as melhorias de desempenho. Não expliquei o suficiente para convencer algumas pessoas no meu comentário original, mas a MS possui documentação explícita sobre como usar as visualizações para melhorar o desempenho. Veja minha resposta (agora com o voto bastante baixo) abaixo.
22413 Mark Brittingham
7

Pode ser mais rápido se você criar uma vista materializada ( com ligação de esquema ). As visualizações não materializadas são executadas exatamente como a consulta regular.

Otávio Décio
fonte
A ligação de esquema tem pouco a ver com desempenho, vincula o esquema da visualização à tabela subjacente, para que permaneça sincronizada e é um pré-requisito para visualizações indexadas.
Sam Saffron
5

Meu entendimento é que, um tempo atrás, uma exibição seria mais rápida porque o SQL Server poderia armazenar um plano de execução e apenas usá-lo em vez de tentar descobrir um em tempo real. Eu acho que os ganhos de desempenho hoje em dia provavelmente não são tão bons quanto antes, mas eu teria que adivinhar que haveria alguma melhoria marginal para usar a exibição.

EJ Brennan
fonte
Este foi o meu entendimento: usado para a matéria, não mais
annakata
Não do ponto de vista de desempenho - funciona como um meio de restrição de acesso. Mas isso seria outro tópico. ;)
AnonJr
Ah, claro, lotes de boas razões para estar usando pontos de vista, nem um único usar consultas matérias: P
annakata
4

Definitivamente, uma exibição é melhor que uma consulta aninhada para o SQL Server. Sem saber exatamente por que é melhor (até ler a postagem de Mark Brittingham), eu havia executado alguns testes e experimentado melhorias de desempenho quase chocantes ao usar uma exibição versus uma consulta aninhada. Depois de executar cada versão da consulta várias centenas de vezes seguidas, a versão de exibição da consulta foi concluída na metade do tempo. Eu diria que isso é prova suficiente para mim.


fonte
Obrigado Jordan ... fico feliz em saber que toda essa teoria funciona no mundo real .
22630 Mark Brittingham
Eu tenho experiência com vista aninhada (vista em vista) e houve um desempenho muito ruim. Quando todas as visualizações foram reescritas para sub-seleções, o desempenho foi muitas vezes mais rápido, portanto, talvez haja um lugar para alguns testes sérios.
Muflix
2

Eu esperaria que as duas consultas fossem executadas de forma idêntica. Uma visão nada mais é do que uma definição de consulta armazenada, não há armazenamento em cache ou armazenamento de dados para uma visão. O otimizador transformará efetivamente sua primeira consulta na sua segunda consulta quando você a executar.

Tony Andrews
fonte
Se a exibição for um pequeno conjunto de campos e esses campos forem cobertos por um índice, o SQL Server é inteligente o suficiente para usar esse índice de cobertura ao preencher a segunda forma de consulta?
21139 AnthonyWJones
1

Tudo depende da situação. As exibições indexadas do MS SQL são mais rápidas que uma exibição ou consulta normal, mas as exibições indexadas não podem ser usadas em um ambiente de banco de dados espelhado (MS SQL).

Uma visualização em qualquer tipo de loop causará séria desaceleração, pois a visualização é preenchida novamente toda vez que é chamada no loop. O mesmo que uma consulta. Nessa situação, uma tabela temporária usando # ou @ para reter seus dados é mais rápida que uma exibição ou uma consulta.

Então, tudo depende da situação.

Dasboot
fonte
0

Não há diferenças práticas e, se você ler BOL, descobrirá que sempre que seu SQL SELECT * FROM X antigo se aproveita do cache do plano etc.

keithwarren7
fonte
0

Deve haver algum ganho trivial em manter o plano de execução armazenado, mas será insignificante.

JosephStyons
fonte
0

O objetivo de uma exibição é usar a consulta repetidamente. Para esse fim, o SQL Server, Oracle etc. geralmente fornecerão uma versão "em cache" ou "compilada" da sua exibição, melhorando assim seu desempenho. Em geral, isso deve ter um desempenho melhor do que uma consulta "simples", embora, se a consulta for realmente muito simples, os benefícios possam ser insignificantes.

Agora, se você estiver fazendo uma consulta complexa, crie a exibição.


fonte
0

Na minha conclusão, o uso da visualização é um pouco mais rápido que uma consulta normal. Meu procedimento armazenado demorou cerca de 25 minutos (trabalhando com conjuntos de registros maiores diferentes e várias junções) e, depois de usar a exibição (sem cluster), o desempenho foi um pouco mais rápido, mas não significativo. Eu tive que usar algumas outras técnicas / método de otimização de consulta para fazer uma mudança drástica.

kta
fonte
Como estamos escrevendo / projetando a consulta é muito importante.
Kta 7/07
Eu descobri que o uso de CTEs para limitar os dados retornados de uma tabela e, em seguida, fazendo todo o trabalho / junções, etc. fora dos
CTEs
0

Selecionar em uma Visualização ou em uma tabela não fará muito sentido.

Obviamente, se o View não possui junções, campos etc. desnecessários, você pode verificar o plano de execução de suas consultas, junções e índices usados ​​para melhorar o desempenho do View.

Você pode até criar um índice nas visualizações para requisitos de pesquisa mais rápidos. http://technet.microsoft.com/en-us/library/cc917715.aspx

Mas se você estiver pesquisando como '% ...%' que o mecanismo sql, não se beneficiará de um índice na coluna de texto. Se você pode forçar seus usuários a fazer pesquisas como '...%', isso será rápido

referida resposta em fóruns asp: https://forums.asp.net/t/1697933.aspx?Which+is+faster+when+using+SELECT+query+VIEW+or+Table+

Mohamad Reza Shahrestani
fonte
0

Contra todas as expectativas, as visualizações são muito mais lentas em algumas circunstâncias.

Descobri isso recentemente quando tive problemas com dados extraídos do Oracle que precisavam ser massageados em outro formato. Talvez 20k linhas de origem. Uma mesinha Para fazer isso, importamos os dados do oracle o mais inalterável possível para uma tabela e, em seguida, usamos visualizações para extrair dados. Tivemos visões secundárias com base nessas visões. Talvez 3-4 níveis de visualizações.

Uma das consultas finais, que extraiu talvez 200 linhas, levaria mais de 45 minutos! Essa consulta foi baseada em uma cascata de visualizações. Talvez 3-4 níveis de profundidade.

Eu poderia pegar cada uma das visualizações em questão, inserir seu sql em uma consulta aninhada e executá-la em alguns segundos.

Descobrimos até que poderíamos gravar cada visualização em uma tabela temporária e consultá-la no lugar da visualização e ainda era muito mais rápido do que simplesmente usar visualizações aninhadas.

O mais estranho foi que o desempenho foi bom até atingirmos um limite de linhas de origem sendo arrastadas para o banco de dados, os desempenhos acabaram de cair de um penhasco no espaço de alguns dias - foram necessárias mais algumas linhas de origem.

Portanto, o uso de consultas extraídas de visualizações que são extraídas de visualizações é muito mais lento que uma consulta aninhada - o que não faz sentido para mim.

Ian
fonte
-1

Passei por esse tópico e só queria compartilhar esta postagem de Brent Ozar como algo a considerar ao usar grupos de disponibilidade.

Relatório de bug do Brent Ozar

JohnH
fonte