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 / 54782
Accepted
db2
db2
Asked: 2013-12-11 06:58:37 +0800 CST2013-12-11 06:58:37 +0800 CST 2013-12-11 06:58:37 +0800 CST

Criando guia de plano para consulta chamada por sp_executesql

  • 772

Para encurtar a história, tenho uma visão chamada vwRelatives que usa recursão CTE para construir árvores genealógicas. Destina-se a ser consultado por uma única pessoa de cada vez.

Isso é executado em cerca de um quarto de segundo:

SELECT * FROM vwRelatives WHERE person_id = 5

Isso (a forma como a consulta é executada no aplicativo) leva mais de 4,5 segundos:

exec sp_executesql N'SELECT * FROM vwRelatives WHERE person_id = @P1',N'@P1 int',5

(Observe que simplifiquei um pouco a consulta. A coisa real tem uma lista de colunas explícita e um ORDER BY, mas a WHEREsemântica é a mesma. Obtenho os mesmos sintomas com qualquer uma das versões.)

Muito provavelmente o SQL Server consegue levar person_id = 5em conta na hora de criar um plano de execução para a primeira query, mas parametrizar isso está fazendo com que toda a view seja executada e depois filtrada por person_id.

Então pensei em criar um guia de plano. E agora tenho dois problemas.

Estes são os passos que estou dando, que parecem não surtir efeito.

Primeiro, execute a consulta 'boa' para colocá-la no cache do plano...

SELECT * FROM vwRelatives WHERE person_id = 5

...em seguida, execute as etapas padrão para transformá-lo em um guia de plano...

--Get the 'good' plan
SET @xml_showplan = (
    SELECT query_plan
    FROM sys.dm_exec_query_stats AS qs 
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
        CROSS APPLY sys.dm_exec_text_query_plan(qs.plan_handle, DEFAULT, DEFAULT) AS qp
        WHERE st.text LIKE N'SELECT * FROM vwRelatives WHERE person_id = 5'
)

--Apply a plan guide to the meat of the sp_executesql query
EXEC sp_create_plan_guide 
    @name = N'vwRelatives_Test_Plan_Guide', 
    @stmt = N'SELECT * FROM vwRelatives WHERE person_id = @P1', 
    @type = N'SQL',
    @module_or_batch = NULL, 
    @params = N'@P1 int', 
    @hints = @xml_showplan;

Isso é concluído com êxito, mas quando executo a instrução sp_executesql original novamente, ainda leva 4,5 segundos. Tenho o Profiler em execução e os eventos Plan Guide Success e Plan Guide Unsuccessful estão selecionados. Nenhum desses eventos aparece no rastreamento.

O que estou fazendo de errado que está impedindo o SQL Server de ver este guia de plano como uma correspondência para a consulta sp_executesql?

sql-server sql-server-2012
  • 1 1 respostas
  • 1478 Views

1 respostas

  • Voted
  1. Best Answer
    db2
    2013-12-11T07:59:39+08:002013-12-11T07:59:39+08:00

    Para aqueles que se deparam com essa questão tentando criar um guia de plano, a sintaxe que eu tinha originalmente está correta. O motivo pelo qual não estava funcionando (suspeito - não consigo encontrar nenhuma confirmação na documentação) é que a exibição usa um CTE para recursão. Evidentemente, isso o desqualifica do uso do guia de plano.

    Meu problema original era que a exibição recursiva tinha um desempenho ruim quando uma SELECTinstrução era emitida via sp_executesql com parâmetros (o cliente é um banco de dados do Access).

    Finalmente me deparei com esta pergunta mais antiga no Stack Overflow, onde alguém está tendo basicamente o mesmo problema:

    https://stackoverflow.com/questions/4226035/why-does-a-query-slow-down-drastically-if-in-the-where-clause-a-constant-is-repl

    Eu estava começando a me perguntar se precisaria enganar/ajudar o otimizador de consulta enviando a recursão para uma função definida pelo usuário, e isso confirmou a suspeita. Mudei todos os CTEs da exibição para um UDF embutido que usa o @person_idparâmetro diretamente na âncora da recursão e agora é agradavelmente rápido mesmo com sp_executesql.

    Portanto, não é a solução que originalmente pensei que precisaria, mas vou aceitar. (Provavelmente é mais direto dessa maneira também. Não preciso me preocupar em anexar um guia de plano a cada variação sutil da consulta que o Access pode construir.)

    • 5

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

    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

    Conceder acesso a todas as tabelas para um usuário

    • 5 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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