RECORDSETS ACCESS

10- Como Crear RecordSets Rápidos

 

 

Autor: Javier Gómez

Ultima Revisión: 12-Mayo-2007

 

¿ Como pasar de 120 segundos a 7 segundos ?

A continuación expongo 5 métodos distintos de como abrir un RecordSet (registros de una tabla) desde la forma mas normal (pero lenta), hasta otra forma mucho mas rápida, y pasando por varias intermedias.

Esta claro que No siempre lo mas rápido es lo mejor o lo mas conveniente , así que cada rutina es distinta. A veces premia la sencillez pero, en otros casos, puede ser la velocidad. ( Que cada uno aplique lo que le mas le convenga).

Las diferencias de tiempos entre los distintos métodos es más que apreciable. Desde los 120 segundos hasta los 7 segundos, dependiendo del método empleado.

Mi tabla de prueba consta de 45.000 registros y he hecho una interacción de 100 veces para poder apreciar mejor las diferencias de tiempos de cada método empleado. Esta claro que los tiempos absolutos solo sirven de referencia y que cada ordenador pueden variar , pero la "proporción" del tiempo de cada uno de los tiempo No variara sustancialmente.

Constantes Recordset tipos
dbOpenTable Table (Microsoft Jet workspaces only)
dbOpenDynamic Dynamic (ODBCDirect workspaces only)
dbOpenDynaset Dynaset
dbOpenSnapshot Snapshot
dbOpenForwardOnly Forward-only

 

 

Metodo 5 en 120 segundos

Private Sub Command5_Click()
Rem Tiempo 120 Segundos
Rem Sin declarar la variables, por defecto es del tipo as Variant
Rem Usando EOF
Rem Usuando dbOpenDynaset
Rem
Asignando un campo a una cadena Ej: strTest = rst(strCampo)

 

Metodo 4 en 39 segundos

Private Sub Command4_Click()
Rem Tiempo 39 segundos
Rem Declarando las variables correctamente
Rem Usando EOF
Rem Usando dbOpenDynaset
Rem Asignando un campo a una cadena
Ej: strTest = rst(strCampo)

Método 3 en 12 segundos

Private Sub Command3_Click()
Rem Tiempo 12 segundos
Rem Declarando las variables correctamente
Rem Sin usar la expresión EOF y sustituyéndola por un campo contador
Rem Abriendo la Tabla como dbOpenDynaset (es lento, aunque a veces necesario)
Rem Sin asignar un campo a una cadena Ej: Set fld = rst(strCampo)

Método 2 en 9 segundos

Private Sub Command2_Click()
Rem Tiempo 9 segundos
Rem Declarando las variables correctamente
Rem Sin usar la expresión EOF y sustituyéndola por un campo contador
Rem Sin asignar un campo a una cadena Ej: Set fld = rst(strCampo)

Rem Abriendo la Tabla como dbOpenSnapshot (algo mas rapido pero No lo suficiente)
Rem Economizando una variable Dim dbs As DAO.Database (No mejora velocidad)

Método 1 en 7 segundos

Private Sub Command1_Click()
Rem Tiempo 7 segundos
Rem Declarando las variables correctamente
Rem Sin usar la expresión EOF y sustituyéndola por un campo contador
Rem Sin asignar un campo a una cadena. Ej: Set fld = rst(strCampo)
Rem Abriendo la Tabla como dbOpenTable (Muy rapido)
Rem Economizando una variable Dim dbs As DAO.Database (No mejora velocidad)

 

Simplemente hay que crear una Base de Datos nueva y crear un nuevo formulario con 5 controles (botones de comando) y enumerados de la siguiente manera: Command5, Command4 , Command3 , Command2 , Command1

 

Option Compare Database
Option Explicit


Const strTabla As String = "tbl_PALABRAS"
 '<<< Nombre Tabla
Const strCampo As String = "ORIGINAL"     
'<<< Nombre Campo
 

Método 5
Private Sub Command5_Click()
Rem Tiempo 120 Segundos
Rem Sin declarar la variables, por defecto es del tipo as Variant
Rem Usando EOF
Rem Usuando dbOpenDynaset
Rem
Asignando un campo a una cadena Ej: strTest = rst(strCampo)


Dim dbs
Dim rst
Dim strTest
Dim dtmTiempoStart
Dim dtmTiempoFinnish
Dim x

DoCmd.Hourglass True
dtmTiempoStart = Now

Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("SELECT * FROM " & strTabla, dbOpenDynaset)
'<<< Lento
rst.MoveLast

For x = 1 To 100
rst.MoveFirst

Do Until rst.EOF
strTest = rst(strCampo)
rst.MoveNext
Loop
Next x

rst.Close
Set rst = Nothing
Set dbs = Nothing

dtmTiempoFinnish = Now
DoCmd.Hourglass False
MsgBox "FIN"
MsgBox "Total ha tardado= " & Format(dtmTiempoFinnish - dtmTiempoStart, "hh:mm:ss")
End Sub

 


Método 4

Private Sub Command4_Click()
Rem Tiempo 39 segundos
Rem Declarando las variables correctamente
Rem Usando EOF
Rem Usuando dbOpenDynaset
Rem Asignando un campo a una cadena
Ej: strTest = rst(strCampo)


Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim strTest As String
Dim dtmTiempoStart As Date
Dim dtmTiempoFinnish As Date
Dim x As Integer

DoCmd.Hourglass True
dtmTiempoStart = Now

Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("SELECT * FROM " & strTabla, dbOpenDynaset)
'<<< Lento
rst.MoveLast

For x = 1 To 100
rst.MoveFirst

Do Until rst.EOF
strTest = rst(strCampo)
rst.MoveNext
Loop
Next x

rst.Close
Set rst = Nothing
Set dbs = Nothing

dtmTiempoFinnish = Now
DoCmd.Hourglass False
MsgBox "FIN"
MsgBox "Total ha tardado= " & Format(dtmTiempoFinnish - dtmTiempoStart, "hh:mm:ss")

End Sub

 


Método 3

Private Sub Command3_Click()
Rem Tiempo 12 segundos
Rem Declarando las variables correctamente
Rem Sin usar la expresion EOF y sustituyendola por un campo contador
Rem Abriendo la Tabla como dbOpenDynaset (es lento, aunque a veces necesario)
Rem Sin asignar un campo a una cadena Ej: Set fld = rst(strCampo)




Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim fld As DAO.Field
Dim strTest As String
Dim dtmTiempoStart As Date
Dim dtmTiempoFinnish As Date
Dim x As Integer
Dim lngRecCount As Long
Dim lngCounter As Long


DoCmd.Hourglass True
dtmTiempoStart = Now

Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("SELECT * FROM " & strTabla, dbOpenDynaset)
'<< Lento
Set fld = rst(strCampo)

rst.MoveLast
lngRecCount = rst.RecordCount

For x = 1 To 100
rst.MoveFirst

For lngCounter = 1 To lngRecCount
strTest = fld
rst.MoveNext
Next lngCounter
Next x

rst.Close
Set rst = Nothing
Set dbs = Nothing


dtmTiempoFinnish = Now
DoCmd.Hourglass False
MsgBox "FIN"
MsgBox "Total ha tardado= " & Format(dtmTiempoFinnish - dtmTiempoStart, "hh:mm:ss")

End Sub

 


Método 2

Private Sub Command2_Click()
Rem Tiempo 9 segundos
Rem Declarando las variables correctamente
Rem Sin usar la expresion EOF y sustituyendola por un campo contador
Rem Sin asignar un campo a una cadena Ej: Set fld = rst(strCampo)

Rem Abriendo la Tabla como dbOpenSnapshot (algo mas rapido pero No lo suficiente)
Rem Economizando una variable Dim dbs As DAO.Database (No mejora velocidad)



Dim rst As DAO.Recordset
Dim fld As DAO.Field
Dim strTest As String
Dim dtmTiempoStart As Date
Dim dtmTiempoFinnish As Date
Dim x As Integer
Dim lngRecCount As Long
Dim lngCounter As Long


DoCmd.Hourglass True
dtmTiempoStart = Now

Set rst = CurrentDb.OpenRecordset(strTabla, dbOpenSnapshot)
'<< Velocidad Normal
Set fld = rst(strCampo)

rst.MoveLast
lngRecCount = rst.RecordCount

For x = 1 To 100
rst.MoveFirst

For lngCounter = 1 To lngRecCount
strTest = fld
rst.MoveNext
Next lngCounter
Next x

rst.Close
Set rst = Nothing

dtmTiempoFinnish = Now
DoCmd.Hourglass False
MsgBox "FIN"
MsgBox "Total ha tardado= " & Format(dtmTiempoFinnish - dtmTiempoStart, "hh:mm:ss")

End Sub


 


Método 1

Private Sub Command1_Click()
Rem Tiempo 7 segundos
Rem Declarando las variables correctamente
Rem Sin usar la expresión EOF y sustituyéndola por un campo contador
Rem Sin asignar un campo a una cadena. Ej: Set fld = rst(strCampo)
Rem Abriendo la Tabla como dbOpenTable muy rápido (siempre que sea posible)
Rem Economizando una variable Dim dbs As DAO.Database (No mejora velocidad)


Dim fld As DAO.Field
Dim rst As DAO.Recordset
Dim strTest As String
Dim dtmTiempoStart As Date
Dim dtmTiempoFinnish As Date
Dim x As Integer
Dim lngRecCount As Long
Dim lngCounter As Long


DoCmd.Hourglass True
dtmTiempoStart = Now

Set rst = CurrentDb.OpenRecordset(strTabla, dbOpenTable)
'<< Muy Rápido
Set fld = rst(strCampo)

rst.MoveLast
lngRecCount = rst.RecordCount

For x = 1 To 100
rst.MoveFirst

For lngCounter = 1 To lngRecCount
strTest = fld
rst.MoveNext
Next lngCounter
Next x

rst.Close
Set rst = Nothing

dtmTiempoFinnish = Now
DoCmd.Hourglass False
MsgBox "FIN"
MsgBox "Total ha tardado= " & Format(dtmTiempoFinnish - dtmTiempoStart, "hh:mm:ss")
End Sub

  Resumen para poder trabajar con RecordSet de forma rápida:

  • Declarando variables (procurando No usar del tipo Variant)
  • Sin usar la expresión EOF y sustituyéndola por un campo contador.
  • Sin asignar un campo a una cadena. Ej: Set fld = rst(strCampo)
  • Abriendo la Tabla como dbOpenTable (siempre que sea posible).

 

Si alguien conoce (con RecordSets) de algún método mas rápido que el aquí expuesto en ( Command1) agradecería me lo comunicase.

 

© Copyright Javier Gómez - All Rights Reserved

 

 

[Atrás]