As Views são otimizadas quando adiciono uma cláusula WHERE a elas?

28

Faz diferença se você filtrar uma visualização dentro ou fora da visualização?

Por exemplo, existe alguma diferença entre essas duas consultas?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Ou

SELECT Id
FROM MyView
WHERE SomeColumn = 1

E MyViewé definido como

SELECT Id, SomeColumn
FROM MyTable

E a resposta é diferente se a tabela de origem estiver localizada em um servidor vinculado?

Estou perguntando porque tenho que consultar uma tabela grande (linhas de 44mil) duas vezes em um servidor vinculado e obter um agregado dos resultados. Quero saber se devo criar duas visualizações para acessar os dados, uma para cada consulta, ou se posso me safar com uma única visualização e uma WHEREcláusula.

Rachel
fonte
1
por que você usaria uma view se apenas tivesse uma tabela nela?
HLGEM 21/03/12
3
@HLGEM security?
21412 JNK
2
@HLGEM O View, na verdade, contém várias consultas a vários bancos de dados em diferentes servidores e une todas elas por um UNION ALL. É muito mais fácil usar uma Visualização do que ter que reescrever a consulta UNION sempre que eu precisar dos dados.
21412 Rachel Rachel
1
@ datagod Vou manter isso em mente, obrigado :) Nesse caso, há um aplicativo bastante pequeno que coleta dados de vários servidores, executa alguns cálculos e gera vários relatórios. Ele possui seu próprio banco de dados, porque alguns dos cálculos consomem bastante recursos e eu queria separá-lo de todo o resto.
Rachel

Respostas:

12

Você não verá absolutamente nenhuma diferença nos planos ou no desempenho entre essas duas opções. Quando a visualização é consultada, ela é expandida para uma consulta na tabela base, o que significa que a mesma busca ou verificação será usada.

Agora, dependendo do tipo de dados e da seletividade MyColumn, se você deseja criar um índice filtrado na tabela base (quando você muda para o SQL Server 2008+), poderá obter um melhor desempenho, mas isso novamente não será diferente na exibição ou sem.

Aaron Bertrand
fonte
3
E essa pergunta , que está perguntando por que uma consulta com a wherecláusula fora da visualização leva muito mais tempo do que quando é colocada na visualização?
21412 Rachel
1
Se as visualizações não são para desempenho, são apenas para estrutura?
Profimedica
1
As visualizações indexadas do @profimedica podem ser criadas por motivos de desempenho (por exemplo, para armazenar resultados intermediários, como agregados, em vez de calculá-los em tempo de execução). Se uma visualização não for materializada, pode ser por vários motivos: DRY (junção ou filtro comum realizado em várias consultas diferentes), segurança, ofuscação, simplificação de esquema.
Aaron Bertrand
5

Aqui está apenas um exemplo rápido, mostrando que não deve haver diferença. O banco de dados é o AdventureWorksbanco de dados.

Duas definições de visualização:

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

Aqui seria a primeira consulta, com o WHERE cláusula incluída na definição de exibição:

select *
from person.vContactWhere

Aqui está o plano de execução:

insira a descrição da imagem aqui

E a segunda consulta, com a WHEREcláusula não na definição da visualização, mas naSELECT consulta:

select *
from person.vContactNoWhere
where ContactID = 24

Aqui está esse plano de execução:

insira a descrição da imagem aqui

Como você pode ver nesses planos de execução, eles são idênticos com resultados idênticos. Não conheço uma situação em que esse tipo de lógica / design produza resultados diferentes. Então, eu gostaria de dizer que você está seguro de qualquer maneira e seguir com preferência pessoal (ou procedimentos de compras).

Thomas Stringer
fonte
1
E essa pergunta , que está perguntando por que uma consulta com a wherecláusula fora da visualização leva muito mais tempo do que quando é colocada na visualização?
21412 Rachel
1
@ Rachel Acho que o gbn explicou isso muito bem em seu post e no artigo que ele apontou. Não sei mais o que dizer.
Thomas Stringer
Vinculei isso porque, nesse caso, os planos de execução não eram os mesmos, o que é diferente do que sua resposta diz.
21412 Rachel
1
@ Rachel O problema nesse exemplo é uma regra de transformação ausente . Não se aplica apenas a visualizações, mas também a CTEs e outras expressões de tabela. No caso geral, não é válido enviar o predicado para baixo em expressões de tabela contendo funções de classificação, pois isso mudará o resultado. A razão de ser válida nesse caso é porque a Wherecláusula se encaixa no PARTITION BY. O SQL Server 2008 parece ter uma nova regra SelOnSeqPrjpara reconhecer esse caso específico.
Martin Smith
2

Com base no que estou lendo , o SQL usará uma exibição padrão como uma subconsulta ao determinar o plano de execução.

Então, usando minha consulta de exemplo,

SELECT Id
FROM MyView
WHERE SomeColumn = 1

onde MyViewé definido como

SELECT Id, SomeColumn
FROM MyTable

deve gerar o mesmo plano de execução que

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

mas esse plano de execução pode ser diferente do que seria gerado com

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Não tenho certeza se essa resposta seria a mesma para exibições indexadas

Rachel
fonte
Não acho que seja uma substituição explícita de texto assim.
Aaron Bertrand
@AaronBertrand Você pode estar certo. Sinceramente, eu não tenho idéia ... Estou aprendendo enquanto vou :) Essa suposição foi baseada em outras coisas que tenho lido sobre como as visualizações são como macros. Editei a pergunta um pouco para especificar que estou me referindo a visualizações padrão, e não indexadas.
21412 Rachel Rachel
@ Rachel - A substituição acontece com a árvore algebrizada que não está no nível textual.
Martin Smith
@MartinSmith Hrrmm não foi isso que eu disse? Que os planos de execução devem ser os mesmos, não que o texto seja o mesmo? Eu não tenho certeza que eu estou entendendo "árvore algebrized"
Rachel
Foi apenas em resposta ao seu comentário no Q, que diz que "insere o texto de uma View na sua consulta" e no comentário de Aaron acima. Algumas informações sobre os estágios de análise / compilação aqui . Na verdade, sua resposta menciona substituição de texto também. Se é uma distinção que vale a pena fazer. Não tenho certeza! Mas acho que explica por que sp_refreshviewé necessário o que o conceito de substituição de texto não faria.
Martin Smith