Inficiência do JDBC ao executar Query com Join no SQL Server!

9 respostas
faelcavalcanti

Pessoal, estou com uma bronca ao tentar rodar uma query utilizando JDBC , SQL Server 2000 e servidor Tomcat 5.0.x.

No meu caso o problema está na demora da execução do método abaixo:

resultSet = statement.executeQuery();

Segue abaixo um código mais completo sobre o problema da demora acima.

System.out.println( "start" );
			
connection = (Connection) transactionManager.getSession();
statement = connection.prepareStatement( sql );
statement.setInt(1, planejamento.getAno() );
resultSet = statement.executeQuery();
			
System.out.println( "finish" );

Segue abaixo o meu sql que é passado para o prepareStatement.

select p.codigo planejamentoCodigo, m.codigo macroObjetivoCodigo, 
	m.descricao macroObjetivoDescricao, r.codigo resultadoCodigo, 
	r.descricao resultadoDescricao, a.codigo acaoCodigo, a.descricao acaoDescricao, 
	pA.codigo prodAnualCodigo, pA.descricao prodAnualDescricao, 
	pAR.codigo prodAnualRespCodigo, pAR.pontuacao prodAnualRespPontuacao, 
	pAR.segmentoResponsavel prodAnualRespSegRespons, pAR.segmentoExecutor prodAnualRespSegExecutor, 
	u.nome unidadeMedidaDescricao, pTP1.quantidade prodTrimPrevQtde1, 
	pTP2.quantidade prodTrimPrevQtde2, pTP3.quantidade prodTrimPrevQtde3, 
	pTP4.quantidade prodTrimPrevQtde4, pTR1.quantidade prodTrimRealQtde1, 
	pTR2.quantidade prodTrimRealQtde2, pTR3.quantidade prodTrimRealQtde3, 
	pTR4.quantidade prodTrimRealQtde4 
from ((((((((((  (((( sisplan_planejamento p 
	inner join sisplan_macroObjetivo m 
		on p.codigo = m.planejamento ) 
	inner join sisplan_resultado r 
		on m.codigo = r.macrobjetivo ) 
	inner join sisplan_acao a 
		on r.codigo = a.resultado ) 
	inner join sisplan_produtoAnual pA 
		on a.codigo = pA.acao ) 
	inner join sisplan_produtoanualresponsavel pAR 
		on pA.codigo = pAR.ProdutoAnual ) 
	inner join sisplan_unidadeMedida u 
		on u.codigo = pAR.unidadeMedida ) 
	left join sisplan_produtotrimestralPrevisto pTP1 
		on pTP1.ProdutoAnualResponsavel = pAR.Codigo and pTP1.trimestre = 1 ) 
	left join sisplan_produtotrimestralPrevisto pTP2 
		on pAr.Codigo  = pTP2.ProdutoAnualResponsavel  and pTP2.trimestre = 2 ) 
	left join sisplan_produtotrimestralPrevisto pTP3 
		on pAr.Codigo  = pTP3.ProdutoAnualResponsavel and pTP3.trimestre = 3 ) 
	left join sisplan_produtotrimestralPrevisto pTP4 
		on pAr.Codigo  = pTP4.ProdutoAnualResponsavel and pTP4.trimestre = 4 ) 
	left join sisplan_produtotrimestralrealizado pTR1 
		on pTR1.ProdutoAnualResponsavel = pAR.Codigo and pTR1.trimestre = 1 ) 
	left join sisplan_produtotrimestralrealizado pTR2 
		on pAr.Codigo  = pTR2.ProdutoAnualResponsavel  and pTR2.trimestre = 2 ) 
	left join sisplan_produtotrimestralrealizado pTR3 
		on pAr.Codigo  = pTR3.ProdutoAnualResponsavel and pTR3.trimestre = 3 ) 
	left join sisplan_produtotrimestralrealizado pTR4 
		on pAr.Codigo  = pTR4.ProdutoAnualResponsavel and pTR4.trimestre = 4 ) 
where p.ano = 2032 
order by p.codigo, m.codigo, r.codigo, a.codigo

Sendo que quando é selecionado um filtro no formulário .jsp, tenho que restringir como segue abaixo

where p.ano = 2032 and pTP1.trimestre in (1)

Também tentei da forma abaixo e dá no mesmo.

where p.ano = 2032 and pTP1.trimestre = 1

Resumindo no Query Analyser do SQL Server o resultado da busca não dura nem 1 segundo aqui, pois traz os resultado no mesmo instante, sendo que quando mando rodar no java através do comando abaixo, demora uma eternidade e não traz nunca.

resultSet = statement.executeQuery();

Alguém poderia me sugerir alguma dica, mudança ou melhoria. Fiquei sabendo de alguns bugs que o driver do jdbc possui por conta de inficiência durante a execução de algumas queries para bancos específicos, mas será que isto é o caso de ter que ficar mudando de driver ?

Agradeço quem puder me ajudar!!! Grande abraço!!

Obrigado, Rafael Cavalcanti.

9 Respostas

Pedrosa

Qual driver vc está usando? JTDS?

O

Por que o driver JTDS é ruim ?
Qual poderia usar ?
Pergunto isso, porqueê temos um problema de lentidão e estamos achando que é o driver.

Pedrosa

JTDS é o melhor driver para trabalhar com SQL.

http://jtds.sourceforge.net/benchTest.html

_fs

Ao executar no QueryAnalyser pela primeira vez (abrir o programa e rodar a query) também é instantâneo?

14 joins numa query não é algo bom cara, poderia talvez usar uma View.

faelcavalcanti

Olá pessoal. Na verdade o meu problema foi de um sql, em que a própria querie abaixo já resolvia, tal como :

select p.codigo planejamentoCodigo, m.codigo macroObjetivoCodigo, 
 	m.descricao macroObjetivoDescricao, r.codigo resultadoCodigo, 
 	r.descricao resultadoDescricao, a.codigo acaoCodigo, a.descricao acaoDescricao, 
 	pA.codigo prodAnualCodigo, pA.descricao prodAnualDescricao, 
 	pAR.codigo prodAnualRespCodigo, pAR.pontuacao prodAnualRespPontuacao, 
 	pAR.segmentoResponsavel prodAnualRespSegRespons, pAR.segmentoExecutor prodAnualRespSegExecutor, 
 	u.nome unidadeMedidaDescricao, pTP1.quantidade prodTrimPrevQtde1, 
 	pTP2.quantidade prodTrimPrevQtde2, pTP3.quantidade prodTrimPrevQtde3, 
 	pTP4.quantidade prodTrimPrevQtde4, pTR1.quantidade prodTrimRealQtde1, 
 	pTR2.quantidade prodTrimRealQtde2, pTR3.quantidade prodTrimRealQtde3, 
 	pTR4.quantidade prodTrimRealQtde4 
 from ((((((((((  (((( sisplan_planejamento p 
 	inner join sisplan_macroObjetivo m 
 		on p.codigo = m.planejamento ) 
 	inner join sisplan_resultado r 
 		on m.codigo = r.macrobjetivo ) 
 	inner join sisplan_acao a 
 		on r.codigo = a.resultado ) 
 	inner join sisplan_produtoAnual pA 
 		on a.codigo = pA.acao ) 
 	inner join sisplan_produtoanualresponsavel pAR 
 		on pA.codigo = pAR.ProdutoAnual ) 
 	inner join sisplan_unidadeMedida u 
 		on u.codigo = pAR.unidadeMedida ) 
 	left join sisplan_produtotrimestralPrevisto pTP1 
 		on pTP1.ProdutoAnualResponsavel = pAR.Codigo and pTP1.trimestre = 1 ) 
 	left join sisplan_produtotrimestralPrevisto pTP2 
 		on pAr.Codigo  = pTP2.ProdutoAnualResponsavel  and pTP2.trimestre = 2 ) 
 	left join sisplan_produtotrimestralPrevisto pTP3 
 		on pAr.Codigo  = pTP3.ProdutoAnualResponsavel and pTP3.trimestre = 3 ) 
 	left join sisplan_produtotrimestralPrevisto pTP4 
 		on pAr.Codigo  = pTP4.ProdutoAnualResponsavel and pTP4.trimestre = 4 ) 
 	left join sisplan_produtotrimestralrealizado pTR1 
 		on pTR1.ProdutoAnualResponsavel = pAR.Codigo and pTR1.trimestre = 1 ) 
 	left join sisplan_produtotrimestralrealizado pTR2 
 		on pAr.Codigo  = pTR2.ProdutoAnualResponsavel  and pTR2.trimestre = 2 ) 
 	left join sisplan_produtotrimestralrealizado pTR3 
 		on pAr.Codigo  = pTR3.ProdutoAnualResponsavel and pTR3.trimestre = 3 ) 
 	left join sisplan_produtotrimestralrealizado pTR4 
 		on pAr.Codigo  = pTR4.ProdutoAnualResponsavel and pTR4.trimestre = 4 ) 
 where p.ano = 2032 
 order by p.codigo, m.codigo, r.codigo, a.codigo

Onde no where, como existe

where p.ano = 2032

Estava efetuando mais um filtro mas de forma que ficasse dessa forma.

where p.ano = 2032 and (novacondicao)

Onde esta nova condição não era necessária, pois toda a implementação eu já tinha tratado em uma implementação do relatório, via scriplet no jasper reports. Porém, foi uma falha minha não ter percebido isto. Mas valeu o aprendizado.

Quanto a criação de views, com certeza chegou-se ao ponto de ter que criar para minimizar toda essa abstração de forma a unificar esta lógica de acesso. Quanto à versão do driver JDBC não faço a menor idéia, só tenho um [.jar] do SQL Server e não sei como faço para sabê-lo.

Valeu pessoal pela força. Só achei também estranho uma coisa já tenho bastantes mensagens postadas aqui fora esta e estou como se fossem 2(duas) agora.

Obrigado, Rafael Cavalcanti

Pedrosa

Para saber qual driver vc está usando, olhe a classe de conexão?

Class.forName
fbanin

LIPE:
Ao executar no QueryAnalyser pela primeira vez (abrir o programa e rodar a query) também é instantâneo?

14 joins numa query não é algo bom cara, poderia talvez usar uma View.

Me desculpe, mas usar uma view tb não é algo muito bom… o certo é otimizar o máximo possível, fugindo da view…

_fs

Eu desculpo você fbanin :smiley:

Pedrosa

Talvez nesse caso seria bakana usar uma stored procedure.

Criado 7 de junho de 2006
Ultima resposta 8 de jun. de 2006
Respostas 9
Participantes 5