AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 334375
Accepted
J. Mini
J. Mini
Asked: 2023-12-28 06:49:52 +0800 CST2023-12-28 06:49:52 +0800 CST 2023-12-28 06:49:52 +0800 CST

Além de liberar explicitamente o cache ou exigir recompilações, o que recompila um procedimento armazenado completo no SQL Server 2019?

  • 772

Recentemente terminei de ler o Plan Caching no SQL Server 2008 e fiquei confuso. Parece que, além de liberar totalmente o cache do plano ou exigir explicitamente a recompilação de um procedimento armazenado, as recompilações de procedimentos armazenados do SQL Server 2008 em diante são feitas no nível da instrução, e não no nível do procedimento armazenado.

Portanto, além de liberar explicitamente o cache ou exigir recompilações (por exemplo WITH RECOMPILE), o que recompila um procedimento armazenado completo no SQL Server 2019 em vez de apenas recompilar instruções individuais?

Para dar um exemplo de onde estou confuso, considere o procedimento a seguir.

CREATE PROCEDURE FOO AS
BEGIN
   SELECT * INTO #temp1 FROM table1
   INSERT BAR1 SELECT * FROM #temp1
   INSERT BAR2 SELECT * FROM #temp1
END

Posso pensar em muitas coisas que poderiam causar SELECT * INTO #temp1 FROM table1a recompilação, mas seria estranho recompilar sem que as próximas linhas também recompilassem. Isso me faz pensar que deve haver algumas coisas no SQL Server que farão com que procedimentos armazenados inteiros sejam recompilados.

t-sql
  • 2 2 respostas
  • 101 Views

2 respostas

  • Voted
  1. Best Answer
    Erik Darling
    2023-12-29T03:58:07+08:002023-12-29T03:58:07+08:00

    não muito

    Fora o que foi listado na sua pergunta, não há realmente nenhuma causa genérica comum para um procedimento armazenado sempre recompilar um novo plano para cada instrução, pelo menos não para o do seu exemplo.

    O SQL Server oferece algumas maneiras diferentes de rastrear recompilações, mas todas elas estão no nível de instrução. Provavelmente o mais fácil de obter respostas são os Eventos Estendidos. Não há nenhum evento para rastrear a recompilação no nível do objeto, que eu encontrei.

    SELECT
         d.map_value
    FROM sys.dm_xe_map_values AS d
    WHERE d.name = 'statement_recompile_cause'
    ORDER BY
        d.map_key;
    

    No SQL Server 2022, isso lista 23 motivos para recompilação, incluindo, uh, "Não é uma recompilação".

    • Esquema alterado
    • Estatísticas alteradas
    • Compilação adiada
    • Definir alteração de opção
    • Tabela temporária alterada
    • Conjunto de linhas remoto alterado
    • Para permissões de navegação alteradas
    • Ambiente de notificação de consulta alterado
    • PartitionView alterado
    • Opções do cursor alteradas
    • Opção (recompilar) solicitada
    • Plano parametrizado liberado
    • Linearização do plano de teste
    • Plano que afeta a versão do banco de dados alterado
    • Política de forçamento do plano do Query Store alterada
    • Falha ao forçar o plano do Query Store
    • Query Store sem plano
    • A execução intercalada exigia recompilação
    • Não é uma recompilação
    • Dicas do Query Store alteradas
    • Falha no aplicativo de dicas do Query Store
    • Recompilando o Query Store para capturar a consulta do cursor
    • Recompilando para limpar o plano do despachante multiplan

    no entanto

    Estou ciente de algumas coisas que impedem o cache do plano, o que faria parecer que um módulo precisa ser recompilado todas as vezes (embora, na realidade, seja mais como apenas compilar todas as vezes, eu acho).

    1. Chaves simétricas

    Como Paulo observa em sua postagem:

    A segunda opção é incluir uma instrução que marque todo o lote como não armazenável em cache. Declarações adequadas são frequentemente relacionadas à segurança ou de alguma forma sensíveis.

    Isso pode parecer impraticável, mas existem algumas atenuações. Primeiro, a instrução sensível não precisa ser executada – ela apenas precisa estar presente. Quando essa condição for atendida, o usuário que executa o lote nem precisa de permissão para executar a instrução confidencial. Observe com atenção que o efeito está confinado ao lote que contém a declaração sensível.

    Siga o link para alguns exemplos.

    1. Objetos inexistentes

    Ainda não tenho um post publicado sobre isso, mas a ideia geral é que quando há uma IFramificação inexplorada em um procedimento armazenado que faz referência a um objeto que não existe, todo o lote não pode ser armazenado em cache.

    Sinta-se à vontade para acompanhar a demonstração abaixo. Observe que se você tentar obter um plano estimado para o procedimento armazenado conforme descrito abaixo, ou se executá-lo de uma forma que explore a ramificação com o objeto inexistente, ocorrerá um erro.

    /*Create a table if you need to*/
    CREATE TABLE 
        dbo.DinnerPlans
    (
        id bigint IDENTITY,
        name nvarchar(40) NOT NULL,
        seat_number tinyint NULL,
        is_free bit NOT NULL,
    );
    GO
    
    /*First example, with an object that doesn't exist*/
    CREATE OR ALTER PROCEDURE
        dbo.i_live
    (
        @decider bit = NULL
    )
    AS
    BEGIN
        SET NOCOUNT, XACT_ABORT ON;
        
        IF @decider = 'true'
        BEGIN
            SELECT
                dp.*
            FROM dbo.DinnerPlans AS dp;
        END;
        
        IF @decider = 'false'
        BEGIN
            SELECT
                whatever.*
            FROM dbo.AnObjectThatDoesntEvenPretendToExist AS whatever;
        END;
        
        IF @decider IS NULL
        BEGIN
            SELECT
                result = 
                    'please make a decision.'
        END;
    END;
    GO 
    
    /*Say goodbye!*/
    DBCC FREEPROCCACHE;
    
    /*This runs without an error*/
    EXEC dbo.i_live 
        @decider = 'true';
    
    /*But there's no query plan!*/
    SELECT
        object_name =
           OBJECT_NAME(deps.object_id, deps.database_id),   
        deps.type_desc,
        deps.last_execution_time,
        deps.execution_count,
        dest.text,
        query_plan =
            TRY_CAST(detqp.query_plan AS xml)
    FROM sys.dm_exec_procedure_stats AS deps
    OUTER APPLY sys.dm_exec_sql_text(deps.plan_handle) AS dest
    OUTER APPLY sys.dm_exec_text_query_plan(deps.plan_handle, 0, -1) AS detqp;
    GO 
    
    • 4
  2. J.D.
    2023-12-28T12:05:49+08:002023-12-28T12:05:49+08:00

    Isso me faz pensar que deve haver algumas coisas no SQL Server que farão com que procedimentos armazenados inteiros sejam recompilados.

    Claro, você pode definir explicitamente o procedimento armazenado para recompilar toda vez que for executado, com a opção recompile assim:

    CREATE PROCEDURE FOO
    WITH RECOMPILE
    AS
    BEGIN
       SELECT * INTO #temp1 FROM table1
       INSERT BAR1 SELECT * FROM #temp1
       INSERT BAR2 SELECT * FROM #temp1
    END
    

    Opções alternativas também executam o procedimento armazenado com a dica de recompilação:

    EXEC FOO WITH RECOMPILE;
    

    Ou chamando explicitamente o procedimento do sistema sp_recompile:

    EXEC sp_recompile N'dbo.FOO';
    
    • 2

relate perguntas

  • Como alterar as configurações do gerenciador de configuração do servidor SQL usando o TSQL?

  • Como posso obter uma lista de nomes e tipos de coluna de um conjunto de resultados?

  • MS SQL: Use o valor calculado para calcular outros valores

  • Como posso saber se um banco de dados SQL Server ainda está sendo usado?

  • Implementando uma consulta PIVOT

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve