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 / 238099
Accepted
Yunus UYANIK
Yunus UYANIK
Asked: 2019-05-15 01:16:15 +0800 CST2019-05-15 01:16:15 +0800 CST 2019-05-15 01:16:15 +0800 CST

Por que o MSSQL escolhe a varredura no plano de execução?

  • 772

Aqui está minha consulta (é uma consulta do Microsoft Axapta):

(@P1 bigint)
SELECT TOP 1 T1.JOURNALNUM,T1.LINENUM,T1.ACCOUNTTYPE,T1.COMPANY,T1.TXT,
T1.AMOUNTCURDEBIT,T1.CURRENCYCODE,T1.EXCHRATE,T1.TAXGROUP,
T1.CASHDISCPERCENT,T1.QTY,T1.BANKNEGINSTRECIPIENTNAME,
-- *Snipped lots of columns in T1* --
T1.MODIFIEDDATETIME,T1.RECVERSION,T1.PARTITION,T1.RECID 
FROM LEDGERJOURNALTRANS T1 
WHERE (((PARTITION=123123123) AND (DATAAREAID=N'test')) AND (REVRECID=@P1))

Plano de execução atual:

insira a descrição da imagem aqui

Plano atual

Na verdade, existe um índice apropriado na tabela.

Colunas de índice: (PARTITION,DATAAREAID,REVRECID)

Fragmentação: insira a descrição da imagem aqui

Eu tentei força de índice. Este plano de execução (busca de índice + pesquisa de chave) é mais rápido que o plano posterior (varredura de índice):

Plano de Índice de Força

insira a descrição da imagem aqui

insira a descrição da imagem aqui

E tentei:

  • ATUALIZAR ESTATÍSTICAS

  • Mudou a ordem das colunas, por exemplo (REVRECID,PARTITION,DATAAREAID)

Por que o MSSQL escolhe o índice clusterizado?

sql-server index
  • 1 1 respostas
  • 273 Views

1 respostas

  • Voted
  1. Best Answer
    Randi Vertongen
    2019-05-15T02:12:07+08:002019-05-15T02:12:07+08:00

    Estimativas, uma enorme quantidade de colunas selecionadas e pushdown de predicado

    As estimativas da consulta não levam em conta o predicado residual na varredura de um custo mais alto do que a pesquisa de busca + chave para obter todas essas colunas extras do índice clusterizado. Isso resulta na escolha da varredura de índice clusterizado + predicado residual em vez da busca de índice.

    Minha versão é Microsoft SQL Server 2016 (RTM-GDR)

    Essas estimativas de empilhamento de predicado foram aprimoradas no SQL Server 2016 SP1

    Atualização para melhorar o diagnóstico para planos de execução de consulta que envolvem empilhamento de predicado residual no SQL Server 2016

    Para melhorar o diagnóstico do cenário descrito na seção "Sintomas", o SQL Server 2016 Service Pack 1 (SP1) apresenta um novo atributo XML de plano de exibição, Leitura de Linhas Estimadas. Este atributo fornece a contagem estimada de linhas que serão lidas pelo operador antes que o predicado residual seja aplicado. Esta atualização é um complemento ao KB 3107397.

    Isso adiciona o EstimatedRowsRead=""XML ao plano de consulta, no seu caso, isso seria próximo ou corresponderia ao predicado residual se a varredura for escolhida.

    Isso deve resolver seu problema


    Exemplo de predicado residual

    insira a descrição da imagem aqui

    insira a descrição da imagem aqui

    Lendo 1,2 milhões de linhas para retornar 0

    Consulta de verificação de índice Custo total estimado

    EstimatedTotalSubtreeCost="0.00449281">
    

    Consulta de busca de índice Custo total estimado

    EstimatedTotalSubtreeCost="0.00672858">
    

    O que é maior do que as estimativas de varredura de índice devido à não contabilização do predicado residual, e é por isso que o plano de menor desempenho foi escolhido.


    A principal solução

    A principal solução seria atualizar para pelo menos o SP1 para adicionar o:

    Atualização para melhorar o diagnóstico para planos de execução de consulta que envolvem empilhamento de predicado residual no SQL Server 2016

    Você deve corrigir mais cedo e com mais frequência, já que o SP2 CU6 foi lançado em 19 de março de 2019 , essa seria uma escolha muito melhor.

    Outra observação lateral, o SP1 para SQL Server 2016 adiciona muitos recursos adicionais , como OLTP na memória, compactação, índices Columnstore, ....


    Outras soluções alternativas que podem ou não valer a pena mencionar

    • Selecionando menos colunas se elas não forem necessárias
    • Adicionando todas essas colunas às colunas incluídas do índice NC
    • Você pode tentar desativar as metas de linha com OPTION(QUERYTRACEON 4138) (talvez)
    • Usando a WITH(INDEX))dica

    Comparação com o SQL Server 2016 SP1

    ao executar uma consulta parecida com a sua, forçando o índice clusterizado a ser usado em uma versão SQL2016 SP1: insira a descrição da imagem aqui

    O custo de subárvore estimado é muito maior.

    EstimatedTotalSubtreeCost="93.6951"
    

    Onde seu custo de subárvore estimado para a varredura de índice clusterizado

    <RelOp AvgRowSize="4788" EstimateCPU="1.36996" EstimateIO="185.267" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Clustered Index Scan" NodeId="1" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="0.00448209" TableCardinality="1245280">
    

    É baixo

    EstimatedTotalSubtreeCost="0.00448209"
    

    Com a principal diferença sendo

    EstimatedRowsRead="1000000"
    

    mostrado ao executar a consulta no SQL 2016 com SP1 aplicado.

    E ao testar com o índice NC especificado

    CREATE INDEX IX_PARTITION_DATAAREAID_REVRECID
    ON dbo.LEDGERJOURNALTRANS(PARTITION,DATAAREAID,REVRECID);
    
    <RelOp AvgRowSize="980" EstimateCPU="0.0001581" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Clustered Index Seek" NodeId="4" Parallel="false" PhysicalOp="Clustered Index Seek" EstimatedTotalSubtreeCost="0.0032831" TableCardinality="1000000">
    

    o EstimatedTotalSubtreeCost para a busca de índice (não total para o plano inteiro) também é baixo:

     EstimatedTotalSubtreeCost="0.0032831
    

    e o custo total estimado da subárvore para minha consulta de teste é muito próximo do seu

    EstimatedTotalSubtreeCost="0.00657048">
    
    • 5

relate perguntas

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

  • Quanto "Padding" coloco em meus índices?

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

  • O que significa "índice" em RDBMSs? [fechado]

  • Como criar um índice condicional no MySQL?

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