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 / 36552
Accepted
Kahn
Kahn
Asked: 2013-03-14 01:05:29 +0800 CST2013-03-14 01:05:29 +0800 CST 2013-03-14 01:05:29 +0800 CST

O planejador de consulta do SQL Server 2008 falha após soltar e recriar o índice

  • 772

Recentemente, executamos um script em nosso banco de dados de produção que eliminaria e recriaria dinamicamente centenas de índices como índices filtrados. Embora este script tenha sido executado perfeitamente em todos os outros testes anteriores, agora, depois deste, o cache do plano de consulta do SQL Server está se comportando de maneira estranha.

O planejador de execução revela que estão sendo usados ​​índices errados que retornam milhões de linhas, quando apenas algumas deveriam corresponder. Quando os índices estão corretos, o plano de execução mostra que o SQL Server resolve usar o índice Scan em oposição ao índice Seek, fornecendo resultados muito inferiores aos ideais. Com dicas de tabela como WITH(INDEX(indexname)) ou WITH(FORCESEEK) nos locais apropriados, isso pode ser corrigido. INNER LOOP JOIN também corrige alguns deles.

No entanto, o problema é que, mesmo quando esses novos índices filtrados são descartados e recriados como eram antes, o plano de consulta permanece o mesmo. O cache do plano de consulta foi limpo, o banco de dados foi restaurado para um ambiente diferente, as estatísticas foram atualizadas e, obviamente, os índices foram reconstruídos para que não sejam fragmentados.

Atualmente, esse é um problema crítico que ninguém tem ideia de como consertar. Embora possamos forçar o SQL Server a usar os planos corretos, simplesmente não é uma solução para a infinidade de softwares que teriam que ser atualizados com ele e, obviamente, um banco de dados onde você precisa apontar manualmente como lidar com consultas não é uma opção .

Então, qualquer ajuda seria bem-vinda.

Editar: Conseguimos corrigir uma consulta descartando os índices, recriando-os novamente como filtrados e, em seguida, executando um UPDATE STATISTICS tablename WITH FULLSCAN. Isso corrigiu parte do problema e duas junções estavam funcionando corretamente. Depois disso, tivemos que fazer uma alteração separada em um índice de várias colunas que não estava envolvido no script de índice original, para incluir uma das colunas usadas na junção. Essas duas alterações juntas permitiram que o planejador de consulta resolvesse usar os índices corretos com Seek em vez de Scan.

A teoria agora é que, devido a uma falha anterior, o banco de dados aparentemente foi restaurado excluindo o banco de dados subjacente e criando um novo a partir do backup, em vez de apenas usar REPLACE como antes. Isso teria de alguma forma desconectado os metadados do masterdb, como planos de execução, todo o cache e outros enfeites do banco de dados, resultando em um novo banco de dados massivo sem planos existentes para lidar com consultas. Isso, agrupado com uma atualização de estatísticas aparentemente falha nos índices recém-criados, teria produzido um cenário em que o SQL Server não tinha ideia de como resolver as várias consultas com as quais estava sendo bombardeado.

No entanto, não estou convencido de que isso ainda seja suficiente, já que alguns dos comportamentos, como alterar o índice de várias colunas e o fato de que nenhuma atualização de estatísticas foi necessária em nenhum dos ambientes de teste anteriores nos últimos 2 meses de testes, parece deixar transparecer que algo mais deu errado.

sql-server sql-server-2008
  • 1 1 respostas
  • 1067 Views

1 respostas

  • Voted
  1. Best Answer
    Kahn
    2013-03-16T02:16:30+08:002013-03-16T02:16:30+08:00

    Bem, agora o problema está resolvido:

    Embora pareça lógico usar índices filtrados (NOT NULL), para reduzir o tamanho do banco de dados e, como dizem muitas fontes na web, aumentar o desempenho, a realidade parece ser algo totalmente diferente.

    Em termos leigos, o planejador de consultas do SQL Server resolve até mesmo suas junções internas básicas sem fazer suposições quanto ao conteúdo das colunas. Mesmo que os valores NULL não formem uma junção, eles devem ser incluídos no índice da coluna para que o planejador de consulta o use, a menos que especificado de outra forma com predicados como WHERE joinCol_ID IS NOT NULL. Basicamente, o SQL Server não usa índices filtrados para junções, a menos que as próprias consultas sejam modificadas para contabilizar o valor do filtro. Em vez disso, ele criará novas estatísticas nessas colunas e/ou usará uma varredura de índice clusterizado ou outros índices incluindo a coluna, o que considerar mais eficaz. Usar índices filtrados em chaves estrangeiras é, portanto, uma ideia absolutamente horrível.

    Ainda não temos ideia de como meses de teste em vários outros ambientes nunca produziram os mesmos resultados fora deste único banco de dados, mas é assim que deve funcionar. Aparentemente, algo que até onde sabemos não está relacionado a cache, estatísticas ou configurações, fez com que o banco de dados de produção se comportasse de maneira diferente e detectasse e usasse corretamente os índices filtrados, enquanto todos os ambientes de teste simplesmente usavam os índices antigos (visto que os índices foram descartados e recriados com o mesmo nome, isso parece uma teoria válida mesmo que não haja nenhuma prova real).

    Portanto, a lição da história: a Web está repleta de exemplos de como os índices filtrados são subutilizados e de como eles podem ser incríveis. Mas essa séria desvantagem nunca apareceu, exceto como um pensamento incômodo no fundo da minha cabeça dizendo "se eles são tão bons, então por que os valores NULL não são filtrados dos índices por padrão, já que eles apenas ocupam espaço e servem apenas a um propósito em circunstâncias especiais"? Bem, agora eu sei por quê. :)

    • -1

relate perguntas

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

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

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

  • Downgrade do SQL Server 2008 para 2005

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