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 / 280899
Accepted
ChrisF
ChrisF
Asked: 2020-12-05 03:29:41 +0800 CST2020-12-05 03:29:41 +0800 CST 2020-12-05 03:29:41 +0800 CST

Impedir que o SQL aparentemente execute uma subconsulta cara

  • 772

Eu tenho um procedimento armazenado do formulário:

CREATE PROCEDURE StoredProcedure
    @SearchString NVARCHAR(MAX),
    @ComparisonType INT
AS
BEGIN

    SELECT  A.Value1,
            B.Value1,
            C.Value1,
            ...
    FROM TableA as A
    INNER JOIN TableB as B on B.Key1 = A.Key1
    INNER JOIN TableC as C on C.Key2 = B.Key2
    WHERE A.DateValue > '2020-10-01'
    And 1 = CASE @SearchString
        WHEN N'' THEN 1
        ELSE
            CASE @ComparisonType
                WHEN 0 THEN -- potentially expensive query 1 referencing TableC
                WHEN 1 THEN -- potentially expensive query 2 referencing TableC
                WHEN 6 THEN -- potentially expensive query 3 referencing TableC
                WHEN 8 THEN -- potentially expensive query 4 referencing TableC
                WHEN 10 -- potentially expensive query 5 referencing TableC
                ELSE 0
            END
        END
END

Mesmo quando é chamado com @SearchStringdefinido para N''a consulta, leva um minuto e meio para ser executado. Se eu remover as partes da "consulta potencialmente cara", a consulta retornará os dados esperados praticamente instantaneamente.

Pelo que li, o acima não deve avaliar nada na ELSEparte da CASEdeclaração externa, @SearchStringentão N''por que ela age como se fosse?

Se isso estiver funcionando conforme o esperado, como codifico isso para forçar o SQL a não executar as partes de "consulta potencialmente cara"?

Estou tentando entender por que eles parecem afetar a consulta principal, apesar dos meus esforços para garantir que eles não sejam chamados.

sql-server query-performance
  • 2 2 respostas
  • 110 Views

2 respostas

  • Voted
  1. J.D.
    2020-12-05T04:27:25+08:002020-12-05T04:27:25+08:00

    Se você adicionar OPTION (RECOMPILE)ao final da WHEREcláusula para que fique assim, o procedimento será executado mais rápido agora?

    WHERE A.DateValue > '2020-10-01'
        And 1 = CASE @SearchString
            WHEN N'' THEN 1
            ELSE
                CASE @ComparisonType
                    WHEN 0 THEN -- potentially expensive query 1 referencing TableC
                    WHEN 1 THEN -- potentially expensive query 2 referencing TableC
                    WHEN 6 THEN -- potentially expensive query 3 referencing TableC
                    WHEN 8 THEN -- potentially expensive query 4 referencing TableC
                    WHEN 10 -- potentially expensive query 5 referencing TableC
                    ELSE 0
                END
            END
    OPTION (RECOMPILE)
    

    Nesse caso, você provavelmente tem um problema de detecção de parâmetros que pode estar causando a geração de planos de execução ruins com estimativas de cardinalidade ruins. Se você atualizar sua postagem com seu plano de execução, podemos identificar exatamente como isso está acontecendo.

    Se for esse o caso, este é um bom artigo sobre Parameter Sniffing e OPTION (RECOMPILE) .

    Observe que eu geralmente uso apenas OPTION (RECOMPILE) para depuração para confirmar rapidamente um problema de detecção de parâmetro e tentar resolver o problema subjacente. Existem casos de uso para OPTION (RECOMPILE), no entanto, é uma compensação por pequenos acertos de desempenho, pois a consulta é recompilada toda vez que é executada.

    Brent Ozar tem uma série incrível de posts no blog sobre questões de Parameter Sniffing. Muitos para vincular individualmente para ser honesto, então aqui está a página raiz que vincula os principais importantes: Parameter Sniffing

    • 2
  2. Best Answer
    nbk
    2020-12-05T04:54:25+08:002020-12-05T04:54:25+08:00

    Inspecione o @ComparisonTypevalor primeiro para obter o valor do parâmetro desejado e, em seguida, use esse valor na consulta original.

    Isso permitirá que o SQL Server execute apenas a consulta necessária sempre que o procedimento de armazenamento for chamado.

    CREATE PROCEDURE StoredProcedure
        @SearchString NVARCHAR(MAX),
        @ComparisonType INT
    AS
    BEGIN
    DECLARE @result SMALLINT;
    IF (@SearchString = '')
    BEGIN
       SET   @result = 0;
    END
    ELSE
        BEGIN
          IF (@ComparisonType = 0)
            BEGIN
               SELECT @result =  A   FROM TableC
            END
          IF (@ComparisonType = 1)
            BEGIN
               SELECT  @result =  B   FROM TableC
            END
          IF (@ComparisonType = 6)
            BEGIN
               SELECT  @result =  C   FROM TableC
            END
          IF (@ComparisonType = 10)
            BEGIN
               SELECT  @result =  D   FROM TableC
            END                                        
          ELSE
          BEGIN
             SET   @result = 0;
          END
        END
        SELECT  A.Value1,
                B.Value1,
                C.Value1
        FROM TableA as A
        INNER JOIN TableB as B on B.Key1 = A.Key1
        INNER JOIN TableC as C on C.Key2 = B.Key2
        WHERE A.DateValue > '2020-10-01'
        And 1 = @result
    END
    
    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

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

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

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