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