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 / 108593
Accepted
sebeid
sebeid
Asked: 2015-07-31 09:32:03 +0800 CST2015-07-31 09:32:03 +0800 CST 2015-07-31 09:32:03 +0800 CST

Procedimento armazenado com recompilação

  • 772

Eu tenho este procedimento armazenado. cada chamada (não é o ideal, mas foi uma tentativa de fazê-lo funcionar de forma mais confiável e rápida a cada vez, em vez de usar um plano antigo em cache)"

O que eles estão dizendo é correto? Existe alguma maneira de fazer isso sem recompilar

   create PROCEDURE [dbo].[VERIFIER_QUEUE]
   @cas_name varchar(20) = NULL,
   @instance_name varchar(50) = NULL,
   @verifier_id int = NULL,
   @applicant_type VARCHAR(20) = NULL

    WITH RECOMPILE     
    AS

   BEGIN 
SET NOCOUNT ON

DECLARE @cas_name_x varchar(20)
DECLARE @instance_name_x varchar(50)
DECLARE @verifier_id_x int
DECLARE @InstanceId INT
...............
sql-server performance
  • 1 1 respostas
  • 1752 Views

1 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2015-08-01T06:05:10+08:002015-08-01T06:05:10+08:00

    Michael Green está certo: os desenvolvedores estão tentando impedir a detecção de parâmetros, que acontece quando o SQL Server compila um plano que é ótimo para um conjunto de valores de parâmetro, mas horrível para outros.

    Você vai querer usar OPTION (RECOMPILE)na(s) declaração(ões) com problemas, não WITH RECOMPILEno procedimento. E eu não recomendaria o "truque" das variáveis ​​locais - apenas torna o código mais confuso; melhor usar OPTIMIZE FOR UNKNOWNem versões modernas se esse for o método que funciona melhor em seu cenário. (Para saber muito mais sobre esse assunto, veja este ótimo post de Paul White .)

    Além disso, se muitos parâmetros forem opcionais (para que a consulta tenha coisas como WHERE col = @param or @param IS NULL), isso é o que chamo de "a pia da cozinha" - às vezes, o SQL dinâmico pode ser uma solução muito mais eficaz. Você não mostrou o resto do seu código, apenas que já estava usando o truque das variáveis ​​locais, mas basicamente ficará assim:

    DECLARE @sql NVARCHAR(MAX) = N'SELECT ... FROM ... WHERE 1 = 1';
    
    IF @cas_name IS NOT NULL
      SET @sql += N' AND cas_name = @cas_name';
    
    IF @instance_name IS NOT NULL
      SET @sql += N' AND instance_name = @instance_name';
    
    IF @verified_id IS NOT NULL
      SET @sql += N' AND verifier_id = @verifier_id';
    
    ...
    
    SET @sql = @sql + N' OPTION (RECOMPILE);';
    PRINT @sql;
    
    EXEC sys.sp_executesql @sql,
      N'@cas_name VARCHAR(20), @instance_name VARCHAR(50), @verifier_id INT, ...',
      @cas_name, @instance_name, @verifier_id, ...;
    

    Essa abordagem de apenas adicionar cláusulas para parâmetros que são realmente fornecidos protege você de armazenar em cache planos com base em diferentes conjuntos de parâmetros (por exemplo, se eu fornecer @FirstNamena primeira execução, o plano de busca naquela coluna que é armazenado em cache não ajudará quando Eu peço @LastName LIKE N'%s%'). O OPTION (RECOMPILE);no final protege você de planos que podem variar muito com base nos valores dos mesmos parâmetros de execução para execução (por exemplo, WHERE name LIKE N'%s%'deve gerar uma forma de plano diferente de WHERE name LIKE N'Q%').

    Isso geralmente funciona melhor com a configuração do servidor optimize for ad hoc workloads, sobre a qual você pode ler aqui e aqui . Essencialmente, o que isso faz é impedir que o cache do plano seja preenchido com todas essas pequenas variações de plano, a menos que sejam usadas mais de uma vez. (Sim, com OPTION (RECOMPILE), o ponto é discutível; no entanto, a configuração do servidor não pode prejudicar o restante de sua carga de trabalho de consulta ad hoc e nunca encontrei uma desvantagem em tê-lo ativado.)

    Isso é bastante seguro contra injeção de SQL, já que você não precisa se preocupar em concatenar a entrada do usuário em strings SQL (todos os parâmetros são fortemente tipados), mas não custa nada ler estes tópicos sobre SQL dinâmico:

    • Protegendo-se contra SQL Injection - Parte 1
    • Protegendo-se contra SQL Injection - Parte 2
    • A Maldição e as Bênçãos do SQL Dinâmico (Erland Sommarskog)
    • Condições de pesquisa dinâmica em T-SQL (Erland também)

    Tenho vídeos sobre minha solução para "a pia da cozinha" aqui e aqui , bem como uma postagem no blog sobre isso .

    • 7

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

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