VELOCIDADE DO ACCESS 2007
Tenho uma aplicação em ACCESS 2007, cuja a finalidade e simular o que acontece na aplicação principal (em .exe), devido a isso, faço uma conexão ADODB no access para acessar o banco de dados da aplicação principal (Oracle 10g), até aqui tudo bem.
O recordset está até que rápido gerando em poucos segundos cerca de 700.000 que é o que o select me traz. Porém quando vou transferir essa quantidade de registros para o Access, fica muito lento, demora cerca de 30min. Se faço a mesma coisa com uma tabela vinculada demora apenas 2min. Alguém sabe porque?
Veja abaixo que estou fazendo no Access para transferir os dados do recordset:
1. Setando o banco de dados corrente do access (Set db = CurrentDb);
2. Gerando uma string de inserção SQL, com a cláusula Insert To;
3. Executando a string assim:
db.Execute(strIns)
Me pergunta e dúvida é: Existe alguma maneira de acelerar o mecanismo de inserção de registros do recordset para uma tabela do banco de dados Access em aberto.
O recordset está até que rápido gerando em poucos segundos cerca de 700.000 que é o que o select me traz. Porém quando vou transferir essa quantidade de registros para o Access, fica muito lento, demora cerca de 30min. Se faço a mesma coisa com uma tabela vinculada demora apenas 2min. Alguém sabe porque?
Veja abaixo que estou fazendo no Access para transferir os dados do recordset:
1. Setando o banco de dados corrente do access (Set db = CurrentDb);
2. Gerando uma string de inserção SQL, com a cláusula Insert To;
3. Executando a string assim:
db.Execute(strIns)
Me pergunta e dúvida é: Existe alguma maneira de acelerar o mecanismo de inserção de registros do recordset para uma tabela do banco de dados Access em aberto.
Está usando commit ou gravando dado a dado?
Eu não sei Usar o Commit... estou usando dado a dado... como faço para usar o Commit?
Veja o código:
Veja o código:
Sub ImportarTempoMax8min()
'Tabela INTEGRATED_READING_T
'Setando banco de dados local
Dim rsLocal As ADODB.Recordset
Set rsLocal = New ADODB.Recordset
'Declarando variáveis de controle
Dim TotReg As Long
Dim IniConect, Inicio
Dim RegAtual As Double
RegAtual = 0
Inicio = Timer
'Apagar registros antigos
strApagar = "DELETE * FROM [INTEGRATED_READING_T]"
rsLocal.CursorLocation = adUseClient
rsLocal.Open strApagar, CurrentProject.Connection, adOpenStatic, adLockOptimistic
Reiniciar:
TempoConectado = 0
'Conectar ao banco de dados
Call Conection 'chama procedimento de conexão com o Oracle
'Marca o inÃÂÂcio da conexão
IniConect = Timer
'Tratamento de erro
If ErrConect = True Then Exit Sub
'Abre o recordset com dados do Oracle
strSQL = "select * from SINERCOM.INTEGRATED_READING_T partition (p" & Particionar(strDataInicial) & ") where VERSION_END Is Null order by 1,2"
rs.CursorLocation = adUseClient
rs.Open strSQL, cn, adOpenStatic, adLockOptimistic
'Pega o total de registros
TotReg = rs.RecordCount
'Vai para o ponteiro onde estava quando expirado a conexão
rs.Move (RegAtual)
Do While Not rs.EOF
'Verifica se o tempo de conexão chegou a 8min (480 segundos)
If TempoConectado > 480 Then
Call FechaConect
GoTo Reiniciar
End If
'Transfere os dados do Oracle para o Access local
strSQL2 = "select * from [INTEGRATED_READING_T]"
rsLocal.Open strSQL2, CurrentProject.Connection, adOpenStatic, adLockOptimistic
rsLocal.AddNew
rsLocal!RESOURCE_ID = rs!RESOURCE_ID
rsLocal!BEGIN_DATE = rs!BEGIN_DATE
rsLocal!VERSION_BEGIN = rs!VERSION_BEGIN
rsLocal!END_DATE = rs!END_DATE
rsLocal!INTEGRATED_VALUE = rs!INTEGRATED_VALUE
rsLocal!RESOURCE_TYPE = rs!RESOURCE_TYPE
rsLocal!USER_NAME = rs!USER_NAME
rsLocal.Update
rsLocal.Close
'Monitorando as informações
RegAtual = RegAtual + 1 'Contador de registros inseridos
TempoConectado = Timer - IniConect 'Marcador do tempo de conexão
rs.MoveNext
Loop
'Fecha a conexão com o Oracle
Call FechaConect
End Sub
iihhh...
alguma novidade?
Alguém ae tem algum material teórico sobre o funcionamento do método Open ADO? O que significa os parâmetros? etc...
alguma novidade?
Alguém ae tem algum material teórico sobre o funcionamento do método Open ADO? O que significa os parâmetros? etc...
Fii, o que demora é o seu do While
Se vc cronometar perceberá que infelizmente o VB é lento neste tipo de operação.
A abertura e preenchimento do RS é rápida por que ele internamente é escrito em C.
Existem ferramentas tanto no access quanto no Oracle para fazer esta migração e serão ferramentas melhores que o VB.
Se precisar mesmo utilizar VB verifique se é possivel criar um código dentro destas aplicações (Macro em Access ou PL em Oracle) que seria simplesmente chamada com o objeto Command do ADO.
Vai precisar sair desse loop que só serve para preencher combos, Grids e afins com uma quantidade reduzida de itens (combo tem limite de integer, cerca de 32.000 registros)
Se vc cronometar perceberá que infelizmente o VB é lento neste tipo de operação.
A abertura e preenchimento do RS é rápida por que ele internamente é escrito em C.
Existem ferramentas tanto no access quanto no Oracle para fazer esta migração e serão ferramentas melhores que o VB.
Se precisar mesmo utilizar VB verifique se é possivel criar um código dentro destas aplicações (Macro em Access ou PL em Oracle) que seria simplesmente chamada com o objeto Command do ADO.
Vai precisar sair desse loop que só serve para preencher combos, Grids e afins com uma quantidade reduzida de itens (combo tem limite de integer, cerca de 32.000 registros)
Ok.
Infelizmente por falta de opção e ordem do usuário da aplicação, tenho que transfetir para um bd Access. Pergunto:
Como faço para então realizar incrementos na tabela sem utilizar o Do While...Loop?
Há como manipular o RS para a Table do Access sem uso de Loop?
Grato.
Infelizmente por falta de opção e ordem do usuário da aplicação, tenho que transfetir para um bd Access. Pergunto:
Como faço para então realizar incrementos na tabela sem utilizar o Do While...Loop?
Há como manipular o RS para a Table do Access sem uso de Loop?
Grato.
cara, sempre quando tenho que fazer isso que está tentando fazer eu concateno tudo em uma String só (no caso srtSQL)... e depois dou um único Insert...
dai seu while fica apenas concatenando String, e o insert é um só... fica bem mais rápido
sacou? gera a string com insert depois da um .execute
há quem diga que pode dar overflow se tiver muitos registros... mas no vb a string pode ter até 65kb se não me engano...
espero ter ajudado!
dai seu while fica apenas concatenando String, e o insert é um só... fica bem mais rápido
sacou? gera a string com insert depois da um .execute
há quem diga que pode dar overflow se tiver muitos registros... mas no vb a string pode ter até 65kb se não me engano...
espero ter ajudado!
faça o seguinte crie o banco no access com o nome que irá utilizar e salve junto ao executavel de seu programa agora troque seu select para este e substitua as palavras em negrito para os nomes solicitados.
strSQL = "select * INTO Coloque o nome da Tabela que receberá os dados IN 'nome do banco.mdb' from SINERCOM.INTEGRATED_READING_T partition (p" & Particionar(strDataInicial) & ") where VERSION_END Is Null order by 1,2"
O nome do banco deve estar entre apostrofe ja o nome da tabela não é necessario veja um exemplo abaixo.
SELECT first.executor, Count(first.concluido) INTO Tabela IN 'teste.mdb'
FROM first
WHERE first.previsao = True
GROUP BY first.executor
ORDER BY Count(first.concluido) DESC;
strSQL = "select * INTO Coloque o nome da Tabela que receberá os dados IN 'nome do banco.mdb' from SINERCOM.INTEGRATED_READING_T partition (p" & Particionar(strDataInicial) & ") where VERSION_END Is Null order by 1,2"
O nome do banco deve estar entre apostrofe ja o nome da tabela não é necessario veja um exemplo abaixo.
SELECT first.executor, Count(first.concluido) INTO Tabela IN 'teste.mdb'
FROM first
WHERE first.previsao = True
GROUP BY first.executor
ORDER BY Count(first.concluido) DESC;
Roberto,
No caso então não preciso da conexão com o Access?? é isso?
No caso então não preciso da conexão com o Access?? é isso?
Isso mesmo,
Você pode usar um banco que vc já possua ou criar um novo.
o select mencionado acima irá salvar todos os dados da consulta em uma tabela e banco escolhido por vc.
por exemplo
SELECT first.executor, Count(first.concluido) INTO Tabela IN 'teste.mdb'
FROM first
WHERE first.previsao = True
GROUP BY first.executor
ORDER BY Count(first.concluido) DESC;
Todos os dados obtidos na consulta será salvo no banco TESTE.MDB dentro de uma tabela de nome TABELA.
Faça um tratamento de erro e caso não de erro exiba o numero de dados transferido.
Você pode usar um banco que vc já possua ou criar um novo.
o select mencionado acima irá salvar todos os dados da consulta em uma tabela e banco escolhido por vc.
por exemplo
SELECT first.executor, Count(first.concluido) INTO Tabela IN 'teste.mdb'
FROM first
WHERE first.previsao = True
GROUP BY first.executor
ORDER BY Count(first.concluido) DESC;
Todos os dados obtidos na consulta será salvo no banco TESTE.MDB dentro de uma tabela de nome TABELA.
Faça um tratamento de erro e caso não de erro exiba o numero de dados transferido.
fiz os teste e não funcionou este select funciona dentro do access e precisa ser adaptado para o vb vou fazer as alterações e posto amanhã
Tópico encerrado , respostas não são mais permitidas