Como posso saber por que uma inserção em uma determinada tabela é lenta?

29

Eu sei que um INSERT em uma tabela SQL pode ser lento por vários motivos:

  • Existência de INSERT TRIGGERs na mesa
  • Muitas restrições impostas que precisam ser verificadas (geralmente chaves estrangeiras)
  • A página é dividida no índice clusterizado quando uma linha é inserida no meio da tabela
  • Atualizando todos os índices não agrupados relacionados
  • Bloqueio de outras atividades na mesa
  • Tempo de resposta de gravação de E / S insuficiente
  • ... alguma coisa que eu perdi?

Como posso saber qual é o responsável no meu caso específico? Como posso medir o impacto das divisões de página versus atualizações de índice não agrupadas em cluster e tudo o mais?

Eu tenho um proc armazenado que insere cerca de 10.000 linhas por vez (de uma tabela temporária), que leva cerca de 90 segundos por 10 mil linhas. Isso é inaceitavelmente lento, pois faz com que outros spids se esgotem.

Examinei o plano de execução e vejo a tarefa INSERT CLUSTERED INDEX e todas as INDEX BUSCAS das pesquisas do FK, mas ainda não me diz ao certo por que leva tanto tempo. Não há gatilhos, mas a tabela possui um punhado de FKeys (que parecem estar adequadamente indexados).

Este é um banco de dados SQL 2000.

BradC
fonte
Você tem a autoexpand ativada em seus arquivos de dados? Isso pode causar problemas de desempenho com a configuração padrão.
Larry Coleman
Estamos falando de usar um criador de perfil? msdn.microsoft.com/pt-br/library/ms187929.aspx
incógnito
@ Larry: Os arquivos de dados têm um espaço livre significativo, então não acredito que o crescimento de arquivos de dados seja um problema. É bom adicionar à lista "coisas para verificar".
BradC
@ user210: A criação de perfil da conclusão da instrução apenas mostra que demorou 90 segundos, não me diz POR QUE. A menos que haja outros eventos que você acha que seriam mais reveladores.
BradC

Respostas:

10

Algumas coisas que você pode olhar ...

Reduza o tamanho do lote de 10000 para algo menor, como 2000 ou 1000 (você não disse quão grande é o tamanho da sua linha).

Tente ativar as estatísticas de IO para ver quanto IO as pesquisas do FK estão levando.

Qual é a espera causada quando a inserção está acontecendo (master.dbo.sysprocesses)?

Vamos começar aqui e ver para onde vamos.

mrdenny
fonte
2
Diminuir o tamanho do lote ajuda (1000 registros leva ~ 25 segundos). Essa é provavelmente a nossa "solução alternativa" atual. Vou ver se consigo determinar as estatísticas de E / S e aguarda (o trabalho é executado sob demanda pelo cliente quando eles têm um arquivo para processar, por isso nem sempre posso prever quando o trabalho será realmente executado).
BradC
7

Brad,

Você deve examinar as estatísticas de espera da sua consulta. Com o SQL2000, você pode usar a sintaxe DBCC SQLPERF ("waitstats") para obter esses detalhes.

SQLRockstar
fonte
6

Posso dizer o que estou procurando ao analisar o desempenho de uma consulta. Talvez ajude.

  • analise o plano de execução da consulta e verifique se há varreduras de índice, varreduras de tabela, uso de funções convert_implicit para tipos de dados sql, paralelismo.
  • execute a consulta com SET STATISTICS IO ON e SET STATISTICS TIME ON para ver o tempo de execução e ler / gravar io para cada inserção.
  • confira waittime de sysprocesses para sua sessão spid.
  • execute o profiler e selecione o modelo padrão. selecione o seguinte: Estatísticas de desempenho (se repetido, seu plano será compilado várias vezes - não é bom), RPC: concluído, SQL: concluído em lote e SQL: início em lote. Adicione a eles contas de linhas da coluna para ver exatamente o número de linhas no lote. Filtre os resultados para ver apenas sua consulta.
  • por fim, colete o contador Page Life Expectancy do windows perfmon e, se estiver abaixo de 300 (5 min), o SQL terá pouca memória. Também colete contadores de disco: comprimento da fila de discos , Tempo do Disco (unidade de arquivos de dados), Tempo de Disco (unidade de arquivos de log) para verificar se há pressão nos discos.
yrushka
fonte
5

Tente usar:

SET STATISTICS IO ON

e

SET STATISTICS PROFILE ON

ESTATÍSTICAS IO

Pode ser útil para informar quais tabelas está executando o maior número de varreduras, leituras lógicas e leituras físicas (eu uso essas três para focar em qual parte do plano de consulta precisa de mais ajustes)

PERFIL ESTATÍSTICO

Retornando principalmente o plano de consulta em um formato tabular, você pode examinar as colunas de E / S e CPU quanto custam mais na consulta (é a varredura da tabela na sua tabela temporária e a classificação que faz para inserir no seu chave em cluster, etc ...)

Andrew Bickerton
fonte