- Este tópico contém 2 respostas, 2 vozes e foi atualizado pela última vez 7 anos, 12 meses atrás por José Laurindo Chiappa.
-
AutorPosts
-
25 de novembro de 2016 às 7:29 pm #108519mpunganParticipante
Tenho o insert abaixo que esta causando muito consumo de CPU, o insert ocorre a cada 5 segundos, com o insert de 5000 mil linhas a cada 5 segundos, o commit esta demorando muito, o commit não termina e começa outro ciclo. Enfileirando as execuções, até o momento fiz um alter nas tabelas para nologging para não gerar log e ver se o processo ficaria mais rápido, mas não surtiu muito efeito. Gostaria de saber se alguém tem alguma dica para melhorar essa performance a nível de banco. Essa aplicação esta usando java.
INSERT INTO data_elements(id, field, data, part) VALUES(:”SYS_B_0″, :”SYS_B_1″, :”SYS_B_2″, SYSDATE)
INSERT INTO messages(part, end_timestamp, mti, start_timestamp) VALUES(SYSDATE, :”SYS_B_0″, :”SYS_B_1″, :”SYS_B_2″) RETURNING id INTO :125 de novembro de 2016 às 8:09 pm #108520José Laurindo ChiappaModeradorColega, seguinte :
a) ABSOLUTAMENTE NÃO BASTA vc botar a tabela em NOLOGGING para que Diminua a geração de redo log (e eu disse DIMINUIR, e não ELIMINAR, pois necessariamente o RDBMS Oracle vai ter que mexer também em tabela internas, que vão gerar um mínimo de redo – eliminar totalmente o redo não dá) – consulte a documentação e https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:3224814814761 para ver que além do NOLOGGING o select TEM que ter um Hint de /*+ APPEND */ e também TEM que estar na forma de SELECT /*+ APPEND */ INTO tabela (sub-SELECT que traz um montão de valores a inserir) : ** SE ** a sua Aplicação não estiver respeitando esses pré-reqs vc NÂO VAI VER DIMINUIÇÂO NENHUMA de redo… Eu IMAGINO que ela não está cumprindo os demais pré-reqs, então Natural que vc não tenhya visto alteração nenhuma…
E reforço a questão do INSERT único inserindo um montão de linhas de uma vez via sub-query : se hoje a sua aplicação trabalha row-by-row (ie, pega uma linha/registro da fonte dos dados, faz um INSERT inserindo essa linha, depois lê a próxima linha da fonte, faz OUTRO insert no banco com essa linha, depois pega um terceira linha, etc), o APPEND Não Vai Funcionar…. E é claro : CADA comando que vc envia pro banco é uma trip até o servidor, tem tráfego de rede, tem PARSE do statement no banco, etc : não tem quem faça isso deixar de ser Ineficiente, por isso muita gente chama isso de slow-by-slow… É lento demais….Caso não dê pra fazer um único INSERT com sub-query, ao menos REDUZA DRASTICAMENTE a qtdade de inserts enviados pro banco, mandando um ARRAY DE DADOS com n registros a inserir pro banco de cada vez : pesquise por ARRAY PROCESSING e BULK COLLECT para mais info…
b) Esses nomes “SYS_B_0”, “SYS_B_1”, etc, parecem indicar que a porquinha da Aplicação ** Não está programada ** para usar BIND VARIABLES, e portanto vc tascou um CURSOR SHARING FORCE pra “forçar” o RDBMS Oracle a fazer um binding : se foi isso SORRY, mas é Ululantemente Óbvio que forçar o banco a refazer um trabalho que Já deveria ter sido feito corretamente já no desenvolvimento VAI SIM gastar CPU : enquanto esse programa não for re-escrito para usar BIND VARIABLES (normalmente via CALLABLE STATEMENT, e de uma forma que o statement (que é o insert) *** Não seja *** fechado e re-aberto a cada execução (mas sim apenas se mude os valors das BIND VARIABLES) , vc NÂO VAI CONSEGUIR chegar na performance que quer, creio…. Veja a Documentação e https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:10128287191505 , https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:5180609822543 , https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:311216724461 , https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:1288401763279 , https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:7832114438832 e https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2320123769177 para algumas discussões e sugestões de POR QUE e COMO fazer BINDING ….
===> O importante a indicar aqui é que é a monstrenga da Aplicação que está dando trabalho em execesso pro banco fazer, então Não É dentro do banco que vc vai resolver isso…
[]s
Chiappa
25 de novembro de 2016 às 8:18 pm #108521José Laurindo ChiappaModeradorUm complemento : como não há ser humano capaz de digitar dados numa taxa do tipo, eu *** imagino ** que, apesar de vc não o dizer, essa tal rotina faz DATA LOAD, ie, programaticamente carrega dados de uma fonte externa – sendo isso, o RDBMS Oracle tem ** diversos ** métodos nativos e de alta-performance para carga de dados, cfrme referido em http://www.oracle.com/technetwork/testcontent/twpdwbestpractices-for-loading-11g-404400.pdf , veja lá se é viável se usar um método nativo do banco ao invés de programinha pra isso…
[]s
Chiappa
-
AutorPosts
- Você deve fazer login para responder a este tópico.