| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/06/2010 11:00:55
|
diego_qmota
JavaEvangelist
![[Avatar]](/images/avatar/e355819c0931a90b594aeb8d6a73587f.jpg)
Membro desde: 28/09/2008 15:44:35
Mensagens: 346
Localização: Paulínia
Offline
|
Bom dia a todos!
Preciso rodar a seguinte consulta na minha aplicação para carregar JList's que me indicam os arquivos txt´s que preciso carregar no meu banco de dados diariamente:
Uso banco ORACLE. O grande problema é que esta tabela está com uma quantidade grande de registros (mais de 50 milhões atualmente e com uma taxa de crescimento de 10 mil registros por dia).
Esta consulta está sendo ineficiente porquê está levando mais de 5 minutos para executar... já indexei os campos que são chave de pesquisa e nada...
Gostaria de receber sugestões para solucionar o problema...
|
"Go ahead, make my day!" |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/06/2010 11:10:36
|
partenon
JavaChild
Membro desde: 27/06/2010 15:08:10
Mensagens: 103
Localização: Brno, Czech Republic
Offline
|
O primeiro passo eh identificar *onde* esta o gargalo. Por exemplo, esta consulta retorna quantos registros? Se retorna 10 milhoes, o gargalo pode ser a rede Outra possivel fonte para o problema eh o tempo que o Oracle esta levando para *executar* a consulta. Neste caso, eh melhor consultar um DBA Serio, isso pode ser causado por literalmente centenas de problemas, que vao desde "hardware ja eh pequeno para o banco de dados" ateh configuracao do Oracle em si, passando por uso inadequado dos indices (ele pode estar usando um indice quando deveria estar usando outro).
|
http://www.google.com/profiles/partenon |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/06/2010 11:11:24
|
partenon
JavaChild
Membro desde: 27/06/2010 15:08:10
Mensagens: 103
Localização: Brno, Czech Republic
Offline
|
Soh de curiosidade: se vc remover o distinct, a performance melhora?
|
http://www.google.com/profiles/partenon |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/06/2010 11:14:13
|
renanreismartins
GUJ Ranger
![[Avatar]](/images/avatar/b43a306ca1e27299a57727ff5c0d4998.jpg)
Membro desde: 19/09/2007 15:19:38
Mensagens: 807
Localização: São Paulo - SP
Offline
|
o unico filtro que vc pode utilizar é realmente soh o fornecedor ?
todos os registros retornados sao realmente necessarios?
abrassss
|
http://renanreismartins.blogspot.com/ - Para apaixonados por desenvolvimento de software |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 08:55:13
|
diego_qmota
JavaEvangelist
![[Avatar]](/images/avatar/e355819c0931a90b594aeb8d6a73587f.jpg)
Membro desde: 28/09/2008 15:44:35
Mensagens: 346
Localização: Paulínia
Offline
|
partenon wrote:O primeiro passo eh identificar *onde* esta o gargalo. Por exemplo, esta consulta retorna quantos registros? Se retorna 10 milhoes, o gargalo pode ser a rede
A consulta retorna poucos registros... Menos de 50 registros.
partenon wrote:Outra possivel fonte para o problema eh o tempo que o Oracle esta levando para *executar* a consulta. Neste caso, eh melhor consultar um DBA  Serio, isso pode ser causado por literalmente centenas de problemas, que vao desde "hardware ja eh pequeno para o banco de dados" ateh configuracao do Oracle em si, passando por uso inadequado dos indices (ele pode estar usando um indice quando deveria estar usando outro).
Isso é meio complicado partenon, porquê eu não conheço o DBA, o servidor fica em outra cidade e para se fazer qualquer requisição, têm que passar por um processo burocrático. Não acho que vão revisar o servidor para verificar isso...
This message was edited 1 time. Last update was at 29/06/2010 08:55:31
|
"Go ahead, make my day!" |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:00:25
|
diego_qmota
JavaEvangelist
![[Avatar]](/images/avatar/e355819c0931a90b594aeb8d6a73587f.jpg)
Membro desde: 28/09/2008 15:44:35
Mensagens: 346
Localização: Paulínia
Offline
|
partenon wrote:Soh de curiosidade: se vc remover o distinct, a performance melhora?
Com certeza... Mas daí terei 30 milhões de registros na minha aplicação para manipular e extrair o que quero ...
Se tiver um jeito de deixar essa bomba para o servidor filtra, não seria melhor?
This message was edited 1 time. Last update was at 29/06/2010 09:02:11
|
"Go ahead, make my day!" |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:00:42
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
SELECT DISTINCT(DATA_ARQUIVO_FONTE) FROM CADCTRL.GDD WHERE FORNECEDOR = ?
Pelo que imagino, a consulta retorna poucos registros (50 datas) mas é necessário fazer um table scan ou um index scan dessa tabela (CADCTRL.GDD) porque nessa consulta em particular o código do fornecedor é uma condição pouco seletiva (digamos que se a tabela tiver 50 milhões de linhas, uma consulta como esta:
SELECT DATA_ARQUIVO_FONTE FROM CADCTRL.GDD WHERE FORNECEDOR = ?
retorne 30 milhões de linhas, por exemplo. É isso que ocorre?
(É melhor você fazer um select count() antes para ver se é isso, porque, como você disse, o servidor está em outra cidade, e se você disparar uma consulta tão grande assim, você irá afogar o link com a outra cidade).
This message was edited 1 time. Last update was at 29/06/2010 09:01:09
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:02:40
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
Você provavelmente irá ter de olhar o modelo de dados e ver se há possibilidade de dividir sua consulta em algumas outras. Por exemplo, pode não fazer sentido você usar uma condição tão abrangente assim em certos casos, e você possa pôr mais cláusulas no "where" para estreitar sua consulta.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:08:00
|
partenon
JavaChild
Membro desde: 27/06/2010 15:08:10
Mensagens: 103
Localização: Brno, Czech Republic
Offline
|
Com certeza... Mas daí terei 30 milhões de registros na minha aplicação para manipular e extrair o que quero ...
Entao acho que isso mata a charada. Voce esta fazendo um distinct em 30 milhoes de registros, para retornar apenas 50. Nao sei exatamente como o Oracle faz (nao sou DBA), mas ate onde sei, ele primeiro pega todos estes 30 milhoes e *depois* faz o "distinct" deles. Por isso que esta tao lento.
Faca um teste: rode a consulta com distinct, pegue os IDs e depois rode a mesma consulta, sem distinct, mas especificando os IDs. Voce vai ver que ele demora muito mais com o distinct do que quando se busca direto pela chave primaria. Entao, assumindo que esta eh a *unica* forma de extrair os dados que vc quer, o problema nao esta em sua aplicacao. Esta na otimizacao do banco de dados
Se isso for suficiente para provar que o problema eh no Oracle, voce pode tentar criar uma tabela que eh populada de tempos em tempos com o resultado desta sua query pesada. Mas sinceramente, eu acho que sua empresa deveria contratar um DBA, nem que seja para dar consultoria de um ou dois dias... Um DBA Oracle pode dar conselhos melhores sobre Oracle do que a maioria de nos aqui do forum de Java
|
http://www.google.com/profiles/partenon |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:10:25
|
diego_qmota
JavaEvangelist
![[Avatar]](/images/avatar/e355819c0931a90b594aeb8d6a73587f.jpg)
Membro desde: 28/09/2008 15:44:35
Mensagens: 346
Localização: Paulínia
Offline
|
renanreismartins wrote:o unico filtro que vc pode utilizar é realmente soh o fornecedor ?
todos os registros retornados sao realmente necessarios?
abrassss
Posso usar um campo a mais somente... mas não dá muita diferença.
Todos os registros são necesários. A consulta só retornar um campo mesmo também...
|
"Go ahead, make my day!" |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:14:36
|
diego_qmota
JavaEvangelist
![[Avatar]](/images/avatar/e355819c0931a90b594aeb8d6a73587f.jpg)
Membro desde: 28/09/2008 15:44:35
Mensagens: 346
Localização: Paulínia
Offline
|
Eu estava pensando se criasse uma tabela para armazenar o resultado dessa consulta (tipo uma unidade de persistência da consulta) e que minha aplicação fosse atualizando quando houvessem mudanças...
Assim na hora de rodar aquela consulta, seria muito mais rápida, porquê eu teria o último resultado dela armazenado.
Mas não sei se seria a melhor solução em termos técnicos (ou seja, se seria gambiarra ou uma solução que muitos adotam)...se alguém atualizasse o banco fora da aplicação, pronto, já furaria o esquema...
|
"Go ahead, make my day!" |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:22:46
|
diego_qmota
JavaEvangelist
![[Avatar]](/images/avatar/e355819c0931a90b594aeb8d6a73587f.jpg)
Membro desde: 28/09/2008 15:44:35
Mensagens: 346
Localização: Paulínia
Offline
|
entanglement wrote:
SELECT DISTINCT(DATA_ARQUIVO_FONTE) FROM CADCTRL.GDD WHERE FORNECEDOR = ?
Pelo que imagino, a consulta retorna poucos registros (50 datas) mas é necessário fazer um table scan ou um index scan dessa tabela (CADCTRL.GDD) porque nessa consulta em particular o código do fornecedor é uma condição pouco seletiva (digamos que se a tabela tiver 50 milhões de linhas, uma consulta como esta:
SELECT DATA_ARQUIVO_FONTE FROM CADCTRL.GDD WHERE FORNECEDOR = ?
retorne 30 milhões de linhas, por exemplo. É isso que ocorre?
(É melhor você fazer um select count() antes para ver se é isso, porque, como você disse, o servidor está em outra cidade, e se você disparar uma consulta tão grande assim, você irá afogar o link com a outra cidade).
É isso que ocorre mesmo. Retornou aproximadamente 30 milhões.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:23:26
|
diego_qmota
JavaEvangelist
![[Avatar]](/images/avatar/e355819c0931a90b594aeb8d6a73587f.jpg)
Membro desde: 28/09/2008 15:44:35
Mensagens: 346
Localização: Paulínia
Offline
|
entanglement wrote:Você provavelmente irá ter de olhar o modelo de dados e ver se há possibilidade de dividir sua consulta em algumas outras. Por exemplo, pode não fazer sentido você usar uma condição tão abrangente assim em certos casos, e você possa pôr mais cláusulas no "where" para estreitar sua consulta.
Ok, vou analisar quais campos podem restringir mais a busca
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:27:01
|
diego_qmota
JavaEvangelist
![[Avatar]](/images/avatar/e355819c0931a90b594aeb8d6a73587f.jpg)
Membro desde: 28/09/2008 15:44:35
Mensagens: 346
Localização: Paulínia
Offline
|
partenon wrote:
Com certeza... Mas daí terei 30 milhões de registros na minha aplicação para manipular e extrair o que quero ...
Entao acho que isso mata a charada. Voce esta fazendo um distinct em 30 milhoes de registros, para retornar apenas 50. Nao sei exatamente como o Oracle faz (nao sou DBA), mas ate onde sei, ele primeiro pega todos estes 30 milhoes e *depois* faz o "distinct" deles. Por isso que esta tao lento.
Faca um teste: rode a consulta com distinct, pegue os IDs e depois rode a mesma consulta, sem distinct, mas especificando os IDs. Voce vai ver que ele demora muito mais com o distinct do que quando se busca direto pela chave primaria. Entao, assumindo que esta eh a *unica* forma de extrair os dados que vc quer, o problema nao esta em sua aplicacao. Esta na otimizacao do banco de dados
Se isso for suficiente para provar que o problema eh no Oracle, voce pode tentar criar uma tabela que eh populada de tempos em tempos com o resultado desta sua query pesada. Mas sinceramente, eu acho que sua empresa deveria contratar um DBA, nem que seja para dar consultoria de um ou dois dias... Um DBA Oracle pode dar conselhos melhores sobre Oracle do que a maioria de nos aqui do forum de Java 
É, pensei em fazer uma tabela auxiliar para isso mesmo... não sei se seria "gambiarra".
|
"Go ahead, make my day!" |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 29/06/2010 09:27:20
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
Você precisa consultar o DBA Oracle da tal empresa para checar se um índice
DATA_ARQUIVO_FONTE + FORNECEDOR + sei lá o quê
ou coisa parecida pode melhorar o resultado da sua consulta. (Eu sou um zero à esquerda em SQL, portanto não sei exatamente que consulta seria boa para essa sua situação em particular.) Deve haver algum índice que não piore os resultados das inserções/atualizações em geral, e melhore sua consulta em particular.
|
|
|
 |
|
|