Lentidão com JDBC(carregar servidor e create statement)

18 respostas
guilherme.dio

Boa noite, já faz um bom tempo que estou com problemas na velocidade durante querys atraves do meu programa

fiz um debug numa simples query e percebi que a query em si esta bem rápida, me retorna rapidinho, porém, para carregar o servidor e criar o statement demora bastante, vou postar a sequencia de um codigo, e peço a ajuda de vocês para mim conseguir arrumar essa lerdeza:

Método de uma classe onde faço uma Query, fiz o debug, e é na linha “11” que está a lentidão:

public int consultaTotalProdução()
    {
        objConecta_BD=new Conecta_BD();
        objConecta_BD.carregarDriver();
        Statement consulta;
        ResultSet retorno;
        String soma="SELECT SUM(dados_inseridos) AS total FROM producao";
        int total=0;
        try
        {
           consulta=objConecta_BD.carregarServidor().createStatement();
           retorno=consulta.executeQuery(soma);
           try
           {
               while(retorno.next())
               {
                   total=retorno.getInt("total");
               }
           }
           finally
           {
               retorno.close();
               consulta.close();
               objConecta_BD.encerrarConexao(objConecta_BD.getConexão());
           }
        }
        catch(Exception e)
        {
            System.out.println(e.getCause());
        }
        return total;
    }

agora este é o metodo que a linha 11 do método anterior chama:

public Connection carregarServidor()
    {
        try
        {
            /* Efetua a conexão com o banco de dados. */
            if (getConexão() == null)
            {
                setConexão(DriverManager.getConnection(getServidor(), getAdmin(), getSenha()));
            }
	} 
        catch (SQLException e)
        {
            System.out.println("Erro com conexão: "+e.getMessage());
	}
	return getConexão();
    }

Obrigado pela atenção de todos, e quem puder ajudar ficarei muito agradecido, pq já estou com esse problema ffaz tempo, e nao consigo resolver, meu programa acaba ficando lento só nas partes que consulto o MySQL

OBS: estou usando MySQL Server+JDBC+MySQL Conector J

18 Respostas

lelodois

Teoricamente não haveria motivos para esta lentidão, vejo que a única possibilidae desta lentidão é a a conexão com a rede.

Uma melhoria seria vc usar uma fábrica de conexões, assim vc criaria o mínimo possível de conexões e reaproveitaria a mesma.

Qual arquitetura da sua app?

guilherme.dio

como asism da app? quer saber como ficao os dados adaptados na GUI?

e minha rede é rapida, eu estou fazendo uma conexão externa ai, se conecta com um DNS que na vdd é meu proprio PC q é um servidor MySQL

mas mesmo que eu coloque localhost ainda fica lento…

e naoe stou dizendo de lentidão de 2,3 segundos, é de 7,8 segundos…MUITO!

ViniGodoy

Use o c3p0 ou o jakarta dbcp, como eu já te recomendei em outro tópico. Conectar no banco é uma tarefa lenta mesmo, sem um pool vc está morto.

guilherme.dio

Vini, onde axo esse c3po(star wars?) ou esse jakarta e oque são eles?

nao entendi sobre “pool”, se tiver como me explicar com algum exemplo agradeço, obrigado!

lelodois

Entenda sobre pool de conexão…
Basicamente você delega a fábrica de conexões a abertura e fechamento das conexões…
Você simplesmente pede as conexões e não fecha, a fábrica fecha…

http://www.guj.com.br/java/17285-exemplo-usando-connection-pool

Coloque suas dúvidas ai

guilherme.dio

parece bem complicado, até desanimei, rsrsrs…

mas então eu vou ter usar Hibernate? e nao posso usar mkais o meu JDBC que ja acostumei?

lelodois

guilherme.dio:
parece bem complicado, até desanimei, rsrsrs…

mas então eu vou ter usar Hibernate? e nao posso usar mkais o meu JDBC que ja acostumei?

Não, este tópico foi simplesmente para vc ver como ele funciona…
Complicado, talvez, a vantagem é que uma vez configurado já era.

De uma olhadinha neste tópico:

http://www.guj.com.br/java/196937-poll-de-conexao-c-aplicacao-desktop---hibernatec3p0-resolvido

guilherme.dio

Vou tentar entender, mas queria implantar com meu JDBC, pq se eu for mexer em hibernate, ai to ferrado, nao sei nada, NADA mesmo.

pra falar a verdade cara, eu comecei a mexer em java em janeiro, estou fazendo curso técnico de informática, e la eu nao aprendo quase nada, estão ensinando ainda estrutura de classes, modelagem, essas besterinhas simples, eu aprendo o resto tudo em casa, to cheio de aposilta e etc…

mas é dificil aprender zohino, muito dificil

agora quero termina esse meu projeto mas, essa lentidão soh atrapalha

lelodois

Cara, não é necessário usar hibernate.

É fácio de configurar, mas se estiver tendo dificuldaes crie a sua fábrica de conexão.
Procure no google como criar a sua, tem mt material.


Abraços

guilherme.dio

se eu criar essa Connection Factory, não vai acabar derrubando o servidor? afinal a conexão vao ficar desde o inicio até o fim da conexão

ViniGodoy

Não. O pool fecha sozinho. O nome do pool que te sugeri é C3P0 (Cê-Três-Pê-Zero), e não C3PO. Eu costumo a usar mesmo o Jakarta-DBCP.
http://commons.apache.org/dbcp/

Usa-lo não tem nada de difícil. Ele implementa um DriverManager (o mesmo que vc usa para obter conexões), e retorna para você uma Connection do Java, comum. Essa mesma connection você vai usar no seu código, com a diferença que chamar close() nela não vai fecha-la, apenas devolve-la para o pool.

O pool se encarrega de abrir mais conexões quando necessário, fechar conexões inativas, reavivar conexões mortas, etc. Tudo isso é configurável. Você diz quantas conexões precisam necessariamente estar abertas o tempo todo, quantas você quer no máximo, quanto tempo uma conexão deve ficar ociosa para ser fechada, etc.

Agora, usar um pool não tem nada de complicado. Na verdade, por ele retornar um Connection Comum, ele geralmente não altera absolutamente nada no código.

Ele também não derruba o servidor justamente pq o pool fecha conexões que estejam inativas há muito tempo, e permite a configuração de limites máximos para o número de conexões simultâneas abertas.

guilherme.dio

Entendi, então se eu introduzir isso em meu projeto vou conseguir melhorar a velocidade visívelmente? dos 8-10 segundos que acabo aguardadando em uma query vou conseguir ver diferença razoável?

lelodois

Sim, pois vc não ficará abrindo conexão toda hora, a conexão será reaproveitada.

guilherme.dio

Mas eu já tenho uma classe de conexão, que puis o nome de Conecta_BD:

package Banco;

// <editor-fold defaultstate="collapsed" desc="Importações">
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
// </editor-fold>

public class Conecta_BD
{
    // <editor-fold defaultstate="collapsed" desc="Declaração: Variáveis">
    private String servidor;
    private String driver;
    private String admin;
    private String senha;
    private Connection conexão;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Setters/Getters">
    public void setServidor(String servidor)
    {
        this.servidor=servidor;
    }

    public String getServidor()
    {
        return this.servidor;
    }

    public void setDriver(String driver)
    {
        this.driver=driver;
    }

    public String getDriver()
    {
        return this.driver;
    }

    public void setAdmin(String admin)
    {
        this.admin=admin;
    }

    public String getAdmin()
    {
        return this.admin;
    }

    public void setSenha(String senha)
    {
        this.senha=senha;
    }

    public String getSenha()
    {
        return this.senha;
    }

    public Connection getConexão()
    {
        return conexão;
    }

    public void setConexão(Connection conexão)
    {
        this.conexão = conexão;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Carrega: Driver">
    public void carregarDriver()
    {
        Properties properties = new Properties();
	try
        {
            properties.load(Conecta_BD.class.getResourceAsStream("Propriedades_BD.properties"));
	} 
        catch (IOException e)
        {
            System.out.println("Erro: Properties");
	}

        setServidor(properties.getProperty("servidor"));
        setDriver(properties.getProperty("driver"));
	setAdmin(properties.getProperty("admin"));
	setSenha(properties.getProperty("senha"));

	try
        {
            Class.forName(getDriver());
	} 
        catch (ClassNotFoundException e)
        {
            System.out.println("Erro ao carregar driver");
	}
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Carrega: Servidor">
    public Connection carregarServidor()
    {
        try
        {
            /* Efetua a conexão com o banco de dados. */
            if (getConexão() == null)
            {
                setConexão(DriverManager.getConnection(getServidor(), getAdmin(), getSenha()));
            }
	} 
        catch (SQLException e)
        {
            System.out.println("Erro com conexão: "+e.getMessage());
	}
	return getConexão();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Encerra Conexão">
    public void encerrarConexao(Connection conexão)
    {
        try
        {
            if (getConexão() != null)
            {
                getConexão().close();
            }
	} 
        catch (SQLException e)
        {
            System.out.println("Erro ao fechar conexão: " + e.getCause());
	}
    }
    // </editor-fold>

}
ViniGodoy

Ótimo. O DriverManager dela é que será substituído pelo DriverManager do pool.

guilherme.dio

Não. O pool fecha sozinho. O nome do pool que te sugeri é C3P0 (Cê-Três-Pê-Zero), e não C3PO. Eu costumo a usar mesmo o Jakarta-DBCP.
http://commons.apache.org/dbcp/

Usa-lo não tem nada de difícil. Ele implementa um DriverManager (o mesmo que vc usa para obter conexões), e retorna para você uma Connection do Java, comum. Essa mesma connection você vai usar no seu código, com a diferença que chamar close() nela não vai fecha-la, apenas devolve-la para o pool.

O pool se encarrega de abrir mais conexões quando necessário, fechar conexões inativas, reavivar conexões mortas, etc. Tudo isso é configurável. Você diz quantas conexões precisam necessariamente estar abertas o tempo todo, quantas você quer no máximo, quanto tempo uma conexão deve ficar ociosa para ser fechada, etc.

Agora, usar um pool não tem nada de complicado. Na verdade, por ele retornar um Connection Comum, ele geralmente não altera absolutamente nada no código.

Ele também não derruba o servidor justamente pq o pool fecha conexões que estejam inativas há muito tempo, e permite a configuração de limites máximos para o número de conexões simultâneas abertas.

Só estou postnado este ultimo tópico para agradecer o Vini, porque finalmente consegui montar meu pool via Jakarta-DBCP, realmente não é dificil de se configurar, e não me fez mudar o código do programa inteiro, simplesmente adicionei as classes corretamente cofnguradas e funcionou, o único problema é entender oque acontece linha a linha.

ViniGodoy

Legal. A primeira vez que usei um pool também fiquei apavorado. Levei algumas horas estudando e xingando. E quando ficou pronto, fiquei envergonhado ao ver o quão simples era.

guilherme.dio

rsrsrsrssr…

bom que ao final realmente fiquei feliz, a velocidade aumentou consíderavelmente

Criado 6 de maio de 2011
Ultima resposta 25 de mai. de 2011
Respostas 18
Participantes 3