Sugestoes - performance view
- Boa tarde !!!
Desenvolvi uma View para fornecer informacoes para gerar os arquivos da NFe, com INNER JOIN e UNION de varias tabelas porque varios modulos geram NFE (vendas, devolucao de clientes, devolucao a fornecedores, etc).
Esse cliente é uma distribuidora de alimentos, que inicia a montagem das cargas as 4 horas da madrugada. O fato é que a pessoa que emite as NFe´s entra no trabalho as 7 horas da manha, e quando inicia seu trabalho de emissao de notas, o pessoal das cargas ainda estao trabalhando e o sistema fica lento.
Estive analisando, e um select nessa view com um where para retornar somente 1 registro, demora as vezes 5s ou mais.
Gostaria da sugestao de voces para me ajudar no que devo fazer, qual analise tenho que fazer para descobrir o que esta lento, onde é o gargalo e o que fazer para resolver esse problema.
Muito obrigado !!!
Respostas
- Boa tarde Sr. Davi
Existem inúmeros fatores para a degradação do desempenho, os índices utilizados, fragmentação da tabela, etc, etc. Comece analisando o plano de execução da sua view para poder identificar tais gargalos. Uma outra dica importante é que você tente substituir esta view por uma stored procedure. Assim você pode aproveitar o cache.
Abraço
Espero ter ajudado
Anderson - DBA/MCP/MCTS/MCITP/MCT - Sua pergunta foi respondida ? Marque-a como tal! www.myspace.com/andersondpa- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:26
Boa Tarde, Davi,
Acabei de fazer um trabalho semelhante ao que você está querendo para um cliente nosso, existe alguns beneficios que consegui ganhar com o Tunning destas views primeiro passo inseri nas views o método AMPULHETA que quer dizer o seguinte no join começa a procura da tabela que contem mais registro para que tem menos registros e no where extamente o contrário da menor para maior, já consegui ligeiros ganhos com isso.A Segunda etapa que fiz foi rodei a query da view com a opção "EXECUTION PLAN" ativada e verifiquei aonde tinha o maior "custo" de acesso e assim fui validando a necessidade de se criar os indices na tabela.
Foi uma boa solução cheguei ganhar muito em algumas queries.
Att,
Denis Graciano
Se a resposta for útil sinalize , obrigado.
- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:29
- Concordo com o Anderson, ao analisar o plano de execução se atente a com ele está buscando a informação, se está fazendo seek ou scan em indices ou se faz direto um table scan. isso pode indicar a necessidade de indices mais eficazes.
analise também como está criado o indice clusterizado, pois ele impacta diretamente nos indices não clusterizados.
sp_updatestats - atualiza a estatistica.
a sugestão da procedure é muito boa também, performance é um assunto complexo e longo.
o que citamos são apenas um dos passoas a serem analisados.
ITILF | MCP | MCTS | MCITP SQL Server 2005 & 2008. http://www.bydocs.com- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:29
- Cara, conforme nossos colegas já falaram, você pode dar uma olhada no plano de execução e verificar qual o operador que está com maior gargalo, veja no número que ele tem embaixo dele... é a percentagem de custo do plano... procure por números altos e tente criar indices nas tabelas....
Outra coisa primordial é ter certeza de que as estatisticas estão atualizadas....
Abraço
PS: Fiquei com uma dúvida, Denis, como conseguiu fazer com que o SQL fizesse os joins de acordo com a ordem que você colocou no SQL?
Ou você apenas trocou a ordem das tabelas?....
Fabiano Neves Amorim - MCTS / MCP - SQLServer - http://fabianosqlserver.spaces.live.com/- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:29
- Davi,
Concordo com a orientação dos colegas.
Mas tenho uma dúvida, como esta a questão de fragmentação dos seus índices?
Pedro Antonio Galvão Junior - MVP - Windows Server System - SQL Server/Coordenador de Projetos/DBA- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:29
- Olá Davi,Uma opção que você tem, é criar uma procedure que chama esta sua, fazendo a execução dela com valores padrões, e marcar essa nova procedure para ser executada na inicialização, assim o plano já é criado automaticamente.Use a seguinte instrução para marcar como proc de inicialização:
sp_procoption @ProcName = 'Nome da procedure', @OptionName = 'Startup', @OptionValue = 'TRUE'
Outra opção que você tem é utilizar o USE PLAN. Você precisa primeiro gerar o plano de execução em XML, usando o SET SHOWPLAN XML. Você então pega esse resultado e passa como hint para a consulta. Mas, isso somente vai funcionar corretamente se sua consulta é totalmente parametrizada.Destas, ainda prefiro a primeira.
Classifiquem as respostas. O Fórum agradece!!- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:30
Todas as Respostas
- Boa tarde Sr. Davi
Existem inúmeros fatores para a degradação do desempenho, os índices utilizados, fragmentação da tabela, etc, etc. Comece analisando o plano de execução da sua view para poder identificar tais gargalos. Uma outra dica importante é que você tente substituir esta view por uma stored procedure. Assim você pode aproveitar o cache.
Abraço
Espero ter ajudado
Anderson - DBA/MCP/MCTS/MCITP/MCT - Sua pergunta foi respondida ? Marque-a como tal! www.myspace.com/andersondpa- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:26
Boa Tarde, Davi,
Acabei de fazer um trabalho semelhante ao que você está querendo para um cliente nosso, existe alguns beneficios que consegui ganhar com o Tunning destas views primeiro passo inseri nas views o método AMPULHETA que quer dizer o seguinte no join começa a procura da tabela que contem mais registro para que tem menos registros e no where extamente o contrário da menor para maior, já consegui ligeiros ganhos com isso.A Segunda etapa que fiz foi rodei a query da view com a opção "EXECUTION PLAN" ativada e verifiquei aonde tinha o maior "custo" de acesso e assim fui validando a necessidade de se criar os indices na tabela.
Foi uma boa solução cheguei ganhar muito em algumas queries.
Att,
Denis Graciano
Se a resposta for útil sinalize , obrigado.
- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:29
- Concordo com o Anderson, ao analisar o plano de execução se atente a com ele está buscando a informação, se está fazendo seek ou scan em indices ou se faz direto um table scan. isso pode indicar a necessidade de indices mais eficazes.
analise também como está criado o indice clusterizado, pois ele impacta diretamente nos indices não clusterizados.
sp_updatestats - atualiza a estatistica.
a sugestão da procedure é muito boa também, performance é um assunto complexo e longo.
o que citamos são apenas um dos passoas a serem analisados.
ITILF | MCP | MCTS | MCITP SQL Server 2005 & 2008. http://www.bydocs.com- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:29
- Cara, conforme nossos colegas já falaram, você pode dar uma olhada no plano de execução e verificar qual o operador que está com maior gargalo, veja no número que ele tem embaixo dele... é a percentagem de custo do plano... procure por números altos e tente criar indices nas tabelas....
Outra coisa primordial é ter certeza de que as estatisticas estão atualizadas....
Abraço
PS: Fiquei com uma dúvida, Denis, como conseguiu fazer com que o SQL fizesse os joins de acordo com a ordem que você colocou no SQL?
Ou você apenas trocou a ordem das tabelas?....
Fabiano Neves Amorim - MCTS / MCP - SQLServer - http://fabianosqlserver.spaces.live.com/- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:29
- Davi,
Concordo com a orientação dos colegas.
Mas tenho uma dúvida, como esta a questão de fragmentação dos seus índices?
Pedro Antonio Galvão Junior - MVP - Windows Server System - SQL Server/Coordenador de Projetos/DBA- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:29
- Agradeço a todos pela ajuda. Vou fazer alguns testes e volto a postar aqui.
Junior, quanto a fragmentação dos indices eu não saberia lhe informar como estao, mas agredeço se você me passar os comandos para ver como estao e para desfragmentar.
Obrigado !!! Fabiano,
Apenas troquei a ordens das tabelas. Uma vez que a view já estava pronta e só precisava melhorar a sua performance.Denis, voce usou a opção WHERE no lugar do JOIN ? Somente isso ja melhora um pouco a Performance ?
- Denis,
Poderiamos analisar os índices e demais informações de fragmentação através dos comandos:
- DBCC SHOW_STATISTICS
- UPDATE STATISTICS
- DBCC SHOWCONTIG
Pedro Antonio Galvão Junior - MVP - Windows Server System - SQL Server/Coordenador de Projetos/DBA
Para verificar fragmentação:
sp_spaceused Tabela
Quanto maior a ultima coluna mais fragmentação e espaço desperdiçado. Isto onera a performance.DaviSaba,
Você conseguiu solucionar o seu problema?
Caso afirmativo poste a solução para que outras pessoas se beneficiem.Att,
Fernanda
“Caso esta resposta tenha ajudado a solucionar sua dúvida, favor clicar em “Marcar como Resposta” para beneficiar outros membros da comunidade que estejam lendo este thread”.- Fernanda, ainda nao consegui resolver. Estou pensando em fazer procedure como sugerio o Anderson. Agora so gostaria de algumas dicas:
Cenario: Trata-se de uma distribuidora de alimentos. O setor de expedição atravez do sistema vai montando a carga, solicitando os produtos para os funcionarios. A carga é montada por rota, ou seja, é definido as cidades que o caminhao vai fazer, e entao sao puxados todos os pedidos dessas cidasdes. Apos concluir os pedidos, sao encaminhados para uma area administrativa para geras as NFes. Entao a pessoa responsavel informa os dados faltantes para emissao da nota, e entao solicita um lote de notas. Esse lote pode conter 100 notas com 10 itens em cada nota que seria 1000 itens.
Minha duvida seria como desenvolver essa procedure:
1) Faria uma procedure que retorna nota por nota, entao o SELECT e LOOP seria feito pela aplicacao. Seria criado outra procedure para retornar dados dos itens, onde tambem seria retornado somente 1 item, realizando outro loop pela aplicacao.
2) A Procedure seria responsavem em fazer o select das 100 notas e devolveria 2 tabela com todas as notas e os itens, nesse caso realizando o loop na procedure.
Em ambos os casos, se puderem me apresentar um modelinho simples somente para eu ter uma ideia e poder concluir esse problema.
Muito Obrigado !!! - Boa tarde !!!
Estou conseguindo fazer a Procedure sem a necessidade de usar loop, estou inserindo os dados em uma tabela temporaria em partes, pois os dados vem de varias tabelas. - Bom dia !!!
Escrevi a Procedure, e de fato o tempo de processamento para retornar apenas 1 registro, baixou de 50 segundos para apenas 1 segundo.
O Problema que esta ocorrendo agora é que quando inicio o computador e executo a procedure, demora os mesmo 50 segundos. A segunda vez que executo, demora 1 segundo.
Eu sei que a primeira vez que a procedure é executa ela é compilada e amarzenada em cache, e o SQL monta o plano de execucao.
Minha pergunta: Tem como eu fazer o SQL compilar a procedure assim que é iniciado, dessa forma quando o usuario executasse pela primeira vez ja demoraria apenas 1 segundo ?
Obrigado. - Olá Davi,Uma opção que você tem, é criar uma procedure que chama esta sua, fazendo a execução dela com valores padrões, e marcar essa nova procedure para ser executada na inicialização, assim o plano já é criado automaticamente.Use a seguinte instrução para marcar como proc de inicialização:
sp_procoption @ProcName = 'Nome da procedure', @OptionName = 'Startup', @OptionValue = 'TRUE'
Outra opção que você tem é utilizar o USE PLAN. Você precisa primeiro gerar o plano de execução em XML, usando o SET SHOWPLAN XML. Você então pega esse resultado e passa como hint para a consulta. Mas, isso somente vai funcionar corretamente se sua consulta é totalmente parametrizada.Destas, ainda prefiro a primeira.
Classifiquem as respostas. O Fórum agradece!!- Marcado como RespostaDaviSaba quarta-feira, 11 de novembro de 2009 10:30
- Obrigado a todos !!!


