Normalmente, crio guias de plano construindo primeiro uma consulta que usa o plano correto e copiando-a para uma consulta semelhante que não. No entanto, isso às vezes é complicado, principalmente se a consulta não for exatamente a mesma. Qual é a maneira correta de criar guias de plano a partir do zero?
O SQLKiwi mencionou a elaboração de planos no SSIS. Existe uma maneira ou uma ferramenta útil para ajudar na elaboração de um bom plano para o SQL Server?
A instância específica em questão é esta CTE: SQLFiddle
with cte(guid,other) as (
select newid(),1 union all
select newid(),2 union all
select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other;
Existe QUALQUER maneira de fazer o resultado vir acima com exatamente 3 distintos guid
s e não mais? Espero poder responder melhor a perguntas no futuro, incluindo guias de plano com consultas do tipo CTE que são referenciadas várias vezes para superar algumas peculiaridades do SQL Server CTE.
fonte
Respostas:
Hoje nao. As expressões de tabela comum não recursivas (CTEs) são tratadas como definições de exibição em linha e expandidas na árvore de consultas lógicas em cada local em que são referenciadas (assim como as definições de exibição regulares) antes da otimização. A árvore lógica da sua consulta é:
Observe as duas âncoras de exibição e as seis chamadas para a função intrínseca
newid
antes que a otimização seja iniciada. No entanto, muitas pessoas consideram que o otimizador deve ser capaz de identificar que as subárvores expandidas eram originalmente um único objeto referenciado e simplificar de acordo. Também houve várias solicitações do Connect para permitir a materialização explícita de uma CTE ou tabela derivada.Uma implementação mais geral faria com que o otimizador considerasse materializar expressões comuns arbitrárias para melhorar o desempenho (
CASE
com uma subconsulta é outro exemplo em que os problemas podem ocorrer hoje). A Microsoft Research publicou um documento (PDF) sobre isso em 2007, embora ainda não esteja implementado até o momento. Por enquanto, estamos limitados à materialização explícita usando coisas como variáveis de tabela e tabelas temporárias.Isso foi apenas uma ilusão da minha parte, e foi muito além da idéia de modificar os guias de plano. É possível, em princípio, escrever uma ferramenta para manipular o XML do plano de programa diretamente, mas sem a instrumentação específica do otimizador, o uso da ferramenta provavelmente seria uma experiência frustrante para o usuário (e o desenvolvedor passou a pensar nisso).
No contexto específico dessa questão, essa ferramenta ainda seria incapaz de materializar o conteúdo da CTE de uma maneira que pudesse ser usada por vários consumidores (para alimentar as duas entradas na junção cruzada nesse caso). O otimizador e o mecanismo de execução suportam spools de vários consumidores, mas apenas para fins específicos - nenhum dos quais poderia ser aplicado a esse exemplo em particular.
Há uma quantidade razoável de flexibilidade aqui. A ampla forma do plano XML é usada para orientar a busca de um plano final (embora muitos atributos sejam completamente ignorados, por exemplo, o tipo de particionamento nas trocas) e as regras normais de busca também sejam consideravelmente relaxadas. Por exemplo, a remoção antecipada de alternativas com base em considerações de custo é desativada, a introdução explícita de junções cruzadas é permitida e as operações escalares são ignoradas.
Há muitos detalhes para aprofundar, mas o posicionamento de Filtros e Escalares de computação não pode ser forçado, e os predicados do formulário
column = value
são generalizados para que um plano que contenhaX = 1
ouX = @X
possa ser aplicado a uma consulta que contenhaX = 502
ouX = @Y
. Essa flexibilidade específica pode ajudar bastante na busca de um plano natural para forçar.No exemplo específico, a união constante de todos sempre pode ser implementada como uma verificação constante; o número de entradas para a União Tudo não importa.
fonte
Não há como (versões do SQL Server até 2012) reutilizar um único spool para as duas ocorrências do CTE. Detalhes podem ser encontrados na resposta do SQLKiwi.Mais abaixo, há duas maneiras de materializar o CTE duas vezes, o que é inevitável pela natureza da consulta. Ambas as opções resultam em uma contagem de guias líquida distinta de 6.
O link do comentário de Martin para o site de Quassnoi em um blog sobre o plano de guiar uma CTE foi uma inspiração parcial para essa pergunta. Ele descreve uma maneira de materializar uma CTE com a finalidade de uma subconsulta correlacionada, que é referenciada apenas uma vez, embora a correlação possa fazer com que ela seja avaliada várias vezes. Isso não se aplica à consulta na pergunta.
Opção 1 - Guia do Plano
Tomando dicas da resposta do SQLKiwi, reduzi o guia a um mínimo que ainda funcionará, por exemplo, os
ConstantScan
nós listam apenas 2 operadores escalares que podem ser expandidos o suficiente para qualquer número.Opção 2 - Verificação remota
Aumentando as despesas da consulta e introduzindo uma verificação remota, o resultado é materializado.
fonte
Com toda a seriedade, você não pode cortar os planos de execução xml do zero. Criá-los usando o SSIS é ficção científica. Sim, é tudo XML, mas eles são de universos diferentes. Olhando para o blog de Paul sobre esse tópico , ele está dizendo "da maneira que o SSIS permite ...", então você pode ter entendido errado? Não acho que ele esteja dizendo "use o SSIS para criar planos", mas sim "não seria ótimo poder criar planos usando uma interface de arrastar e soltar, como SSIS". Talvez, para uma consulta muito simples, você possa gerenciar isso, mas é uma extensão, possivelmente até uma perda de tempo. Trabalho ocupado, você pode dizer.
Se estou criando um plano para uma dica ou um guia de plano do USE PLAN, tenho algumas abordagens. Por exemplo, eu posso remover registros das tabelas (por exemplo, em uma cópia do banco de dados) para influenciar as estatísticas e incentivar o otimizador a tomar uma decisão diferente. Também usei variáveis de tabela em vez de toda a tabela da consulta, para que o otimizador pense que toda tabela contém 1 registro. Em seguida, no plano gerado, substitua todas as variáveis da tabela pelos nomes da tabela original e troque-a como o plano. Outra opção seria usar a opção WITH STATS_STREAM de UPDATE STATISTICS para falsificar estatísticas, que é o método usado ao clonar cópias de bancos de dados somente estatísticas.
Passei algum tempo mexendo nos planos de execução xml no passado e descobri que, no final, o SQL simplesmente diz "Não estou usando isso" e executa a consulta como deseja de qualquer maneira.
Para o seu exemplo específico, tenho certeza de que você sabe que pode usar o número de linhas 3 ou TOP 3 na consulta para obter esse resultado, mas acho que esse não é o seu ponto. A resposta correta seria realmente: use uma tabela temporária. Eu voto positivo:) Não seria uma resposta correta "gastar horas e até dias cortando seu próprio plano de execução XML personalizado, em que você tenta induzir o otimizador a fazer um spool preguiçoso para o CTE, que pode nem funcionar de qualquer maneira, seria inteligente. mas também seria impossível de manter ".
Não tentando ser construtivo lá, apenas minha opinião - espero que ajude.
fonte
Finalmente, no SQL 2016 CTP 3.0, existe uma maneira, tipo de:)
Usando o sinalizador de rastreamento e Eventos Estendidos como detalhado por Dmitry Pilugin aqui , você pode (arbitrariamente) pescar três guids únicas dos estágios intermediários da execução da consulta.
NB Este código NÃO se destina à produção ou uso sério no que se refere à imposição do plano CTE, apenas um olhar alegre sobre um novo sinalizador de rastreamento e uma maneira diferente de fazer as coisas:
Testado na versão (CTP3.2) - 13.0.900.73 (x64), apenas por diversão.
fonte
Descobri que o traceflag 8649 (forçar plano paralelo) induziu esse comportamento para a coluna guia da esquerda nas minhas instâncias de 2008, R2 e 2012. Não precisei usar o sinalizador no SQL 2005 onde o CTE se comportou corretamente. Tentei usar o plano gerado no SQL 2005 nas instâncias superiores, mas ele não foi validado.
Usando a dica, usando um guia de plano, incluindo a dica ou usando o plano gerado pela consulta com a dica ativada em um USE PLAN etc, tudo funcionou.
fonte