CONSULTA SQL MUITO LENTA NA REDE
Olá!
Tenho numa pequena rede um micro que funciona como servidor. Nele encontra-se um banco de dados de CEP.
Uso VB6 com ADO.
Preencho uma ComboBox com todas UFs (estados) e, ao selecionar determinado estado, outra ComboBox é carregada com as cidades desse estado.
Quando a consulta é realizada no micro do BD tudo é rápido, mas quando é realizada noutro micro, demora muito pra carregar o ComboBox com as cidades.
Existe como otimizar o código abaixo?
Tenho numa pequena rede um micro que funciona como servidor. Nele encontra-se um banco de dados de CEP.
Uso VB6 com ADO.
Preencho uma ComboBox com todas UFs (estados) e, ao selecionar determinado estado, outra ComboBox é carregada com as cidades desse estado.
Quando a consulta é realizada no micro do BD tudo é rápido, mas quando é realizada noutro micro, demora muito pra carregar o ComboBox com as cidades.
Existe como otimizar o código abaixo?
Dim strCaminhoBD As String
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
[ô] strCaminhoBD é o local do BD na rede
con.Open [Ô]Provider=Microsoft.Jet.OLEDB.4.0;[Ô] & [Ô]Data Source=[Ô] & strCaminhoBD
Set rs = New ADODB.Recordset
rs.Open [Ô]SELECT DISTINCT Cidade FROM TabCEP WHERE UF=[ô][Ô] & strUF & [Ô][ô][Ô], con, adOpenKeyset, adLockReadOnly
Do While Not rs.EOF
cbo.AddItem rs.Fields([Ô]Cidade[Ô])
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
con.Close
Set con = Nothing
Coloque na sua string de conexão o seguinte parâmetro a mais
con.CursorLocation = adUseClient
con.Open [Ô]Provider=Microsoft.Jet.OLEDB.4.0;Data Source=[Ô] & strCaminhoBD & [Ô];Persist Security Info=False[Ô]
Outra coisa na tabela que esta sendo consultada exclua os itens duplicados
veja se dá certo e optimiza o desempenho
con.CursorLocation = adUseClient
con.Open [Ô]Provider=Microsoft.Jet.OLEDB.4.0;Data Source=[Ô] & strCaminhoBD & [Ô];Persist Security Info=False[Ô]
Outra coisa na tabela que esta sendo consultada exclua os itens duplicados
veja se dá certo e optimiza o desempenho
Filman:
Obrigado pela ajuda, mas (sou novato) qual a diferença entre:
con.CursorLocation = adUseClient
con.CursorLocation = adUseServer
Quando usar cada um deles? E no meu código, qual é o mais rápido?
Obrigado pela ajuda, mas (sou novato) qual a diferença entre:
con.CursorLocation = adUseClient
con.CursorLocation = adUseServer
Quando usar cada um deles? E no meu código, qual é o mais rápido?
No site http://www.macoratti.net/ado_fast.htm encontrei:
Fala do Recordset. é válido para o Connection (con.CursorLocation)???
Citação:[Ô]Se você não precisa fazer atualizações nem se mover para frente e para trás em seu Recordset , não tenha dúvidas utilize o padrão ADO : adUseServer , adOPenForwardOnly e adLockReadOnly. Isto lhe dará um melhor desempenho.
Se você precisar se mover por todo o seu Recordset , o cenário muda , prefira usar o Cursor do lado do cliente - adUseClient , e neste caso utilize adLockReadOnly como tipo de bloqueio (a não ser que você realmente precisa de outro tipo de bloqueio).
Já se você precisar de um Recordset atualizável o Cursor do lado do cliente - adUseClient - irá onerar mais o seu sistema. Utilize AdUseServer.[Ô]
Fala do Recordset. é válido para o Connection (con.CursorLocation)???
Andresnoxi veja bem um solução praticamente definitiva para o seu problema
A consulta é rápida, a conexão com o banco que é um pouco mais demorada, e pelo que vejo você quando vai fazer a consulta realiza a conexão na hora, isso toma um pouco de tempo.
qual o ideal, o ideal é você fazer a conexão ao abrir seu programa, e mante-lo conectado e fechar somente quando sair do programa.
bom esta parte do seu código:
pode ser posta em um módulo com uma função chamada de CONECTAR, depois é só chamar a função no load e um load do form principal.
veja a pequena alteração sugerida
em um módulo cole:
com o modulo acima fica mais fácil de você usar seu programa, basta que você no load do form principal, ou pode ser no load do form de consulta mesmo, coloque
depois na sua consulta basta declarar o recordset assim
a consulta ficara rapida.
lembre-se apenas de fechar a conexão ao sair do form
ou seja no Unload do form coloque
teste ai e diga como ficou
A consulta é rápida, a conexão com o banco que é um pouco mais demorada, e pelo que vejo você quando vai fazer a consulta realiza a conexão na hora, isso toma um pouco de tempo.
qual o ideal, o ideal é você fazer a conexão ao abrir seu programa, e mante-lo conectado e fechar somente quando sair do programa.
bom esta parte do seu código:
Dim con As ADODB.Connection
Set con = New ADODB.Connection
[ô] strCaminhoBD é o local do BD na rede
con.Open [Ô]Provider=Microsoft.Jet.OLEDB.4.0;[Ô] & [Ô]Data Source=[Ô] & strCaminhoBD
pode ser posta em um módulo com uma função chamada de CONECTAR, depois é só chamar a função no load e um load do form principal.
veja a pequena alteração sugerida
em um módulo cole:
Global con As ADODB.Connection
Public Function Conectar(valor As Boolean)
If valor = True Then
If con.State = 1 Then Con.Close[txt-color=#007100] [ô] aqui é verificado se a conexão ja está aberta para evitar erro[/txt-color]
con.CursorLocation = adUseClient
con.Open = [Ô]Provider=Microsoft.Jet.OLEDB.4.0;Data Source=[Ô] & strCaminhoBD & [Ô];Persist Security Info=False[Ô]
Else
Con.Close
End If
End Function
com o modulo acima fica mais fácil de você usar seu programa, basta que você no load do form principal, ou pode ser no load do form de consulta mesmo, coloque
Conectar True
depois na sua consulta basta declarar o recordset assim
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open [Ô]SELECT DISTINCT Cidade FROM TabCEP WHERE UF=[ô][Ô] & strUF & [Ô][ô][Ô], con, adOpenKeyset, adLockReadOnly
Do While Not rs.EOF
cbo.AddItem rs.Fields([Ô]Cidade[Ô])
rs.MoveNext
Loop
a consulta ficara rapida.
lembre-se apenas de fechar a conexão ao sair do form
ou seja no Unload do form coloque
Conecta False
teste ai e diga como ficou
Oi, Marcelo:
Obrigado pela dica. Realmente, acho que funcionará.
Mas eu tenho 3 BDs a conectar. é possÃvel assim?
Ou seja, 3 funções diferentes, uma pra cada BD?
Posso abri-las simultaneamente ao carregar o form?
Como o BD de CEP é grande, e os outros também serão após receber os dados, isso não pesará no desempenho geral do sistema? ou a conexão funciona como um link que não tem peso significativo?
O peso da conexão pode variar de acordo com o tamanho do BD?
Como veem, estou cheio de dúvidas (aprendendo a cada resposta de vocês) - Obrigado!
Obrigado pela dica. Realmente, acho que funcionará.
Mas eu tenho 3 BDs a conectar. é possÃvel assim?
Ou seja, 3 funções diferentes, uma pra cada BD?
Posso abri-las simultaneamente ao carregar o form?
Como o BD de CEP é grande, e os outros também serão após receber os dados, isso não pesará no desempenho geral do sistema? ou a conexão funciona como um link que não tem peso significativo?
O peso da conexão pode variar de acordo com o tamanho do BD?
Como veem, estou cheio de dúvidas (aprendendo a cada resposta de vocês) - Obrigado!
você pode fazer tres funções diferentes, a conexão com o banco não vai ser afetada pelo seu tamanho, porém ai sim poderá afetar o desempenho da consulta, mas não tanto quanto abrir a conexão na consulta.
Marcelo:
ObrigadÃssimo!!! Mudei em todo programa e ficou muito mais rápido em diversos pontos.
Mas quando é no BD de CEP (o maior!), mesmo com algumas alterações que trouxeram melhorias, continua lento quando na rede:
[txt-size=3]
Existe como otimizar essa consulta na rede? Pois dura cerca de 30 segs para carregar o cbo.
Obrigado.
ObrigadÃssimo!!! Mudei em todo programa e ficou muito mais rápido em diversos pontos.
Mas quando é no BD de CEP (o maior!), mesmo com algumas alterações que trouxeram melhorias, continua lento quando na rede:
[txt-size=3]
Dim fldCidade
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open [Ô]SELECT DISTINCT Cidade FROM TabCEP WHERE UF=[ô][Ô] & strUF & [Ô][ô][Ô], con, adUseServer, adOpenKeyset, adLockReadOnly [ô]
Set fldCidade = rs.Fields([Ô]Cidade[Ô])
While Not rs.EOF
cbo.AddItem fldCidade
rs.MoveNext
Wend
[/txt-size]Existe como otimizar essa consulta na rede? Pois dura cerca de 30 segs para carregar o cbo.
Obrigado.
Faça um teste
isto
por isto
isto
rs.Open [Ô]SELECT DISTINCT Cidade FROM TabCEP WHERE UF=[ô][Ô] & strUF & [Ô][ô][Ô], con, adUseServer, adOpenKeyset
por isto
rs.Open [Ô]SELECT DISTINCT Cidade FROM TabCEP WHERE UF=[ô][Ô] & strUF & [Ô][ô][Ô], con, adOpenKeyset, adLockBatchOptimistic
Veja a possibilidade de trabalhar consultando o site dos correios através de um web browser, alem de vc não precisar
de uma base enorme, ainda tem consultas mais precisas, pois essas bases alteram sempre.
Em vb.net sei que da, em vb6 não sei, mas basta vc identificar os nomes dos controles nas paginas do correios, carrega seus valores nessa pagina, e da o comando no botão da pagina, em seguida recupera a resposta para seu sistema.
de uma base enorme, ainda tem consultas mais precisas, pois essas bases alteram sempre.
Em vb.net sei que da, em vb6 não sei, mas basta vc identificar os nomes dos controles nas paginas do correios, carrega seus valores nessa pagina, e da o comando no botão da pagina, em seguida recupera a resposta para seu sistema.
Marcelo:
Desta vez deu errado no meu programa:
resultou
erro número: -2147217900
descrição: Expected query name after EXECUTE
Pesquisei no Google, mas não encontrei como associar os possÃveis motivos do erro a alteração realizada.
Desta vez deu errado no meu programa:
resultou
erro número: -2147217900
descrição: Expected query name after EXECUTE
Pesquisei no Google, mas não encontrei como associar os possÃveis motivos do erro a alteração realizada.
Tópico encerrado , respostas não são mais permitidas