Esto va ha ser muy muy duro.
Ernesto Revilla
aerd en retemail.es
Lun Jul 21 20:39:38 CEST 2003
Buneas,
>Ya se sabe, es duro empezar de nuevo.
>Pretendo migrar de Windows + Visual Basic + Access a Todo + Python +
>Todo
Que te sea leve. La sensación será del cambio de una jaula de oro
(falsificado) contra la absoluta libertad, que es inicialmente algo más
trabajoso, pero de da posibilidades prácticamente ilimitadas, especialmente
en el ámbito de Internet.
...DAO vs. mxODBC
>He realizado el mismo ejemplo en Visual Basic y aquí pasa algo.
>Si tratamos los insert mediante comandos SQL mx supera a VB "Genial",
>pero en el apartado DAO mientras con Python he tardado en meter 1000
>registros 9 segundos en VB sólo he tardado 0.5 segundos.
Sí, esto se debe a que la maquinaria de Python.Com realiza una serie de
validaciones.
Vemos algunos ejemplos:
Ejemplo 1:
from win32com.client import Dispatch
e=Dispatch("DAO.DBEngine.35")
db=e.OpenDatabase("c:/kk.mdb")
rs=db.OpenRecordset("SELECT * FROM kk")
from time import time
t=time()
for i in range(100000):
rs.AddNew()
rs.Fields("Id").Value=i
rs.Fields("Nombre").Value="kkkkkk"
rs.Update()
print "tiempo: %s" % (time()-t)
db.Close()
100.000 registros: aprox. 46s
El acceso a rs.Fields es muy costoso. También desde VisualBasic
(rs.Fields("NombreCampo")). Con rs!NombreCampo se realiza un "EarlyBinding",
por lo que se optimiza el acceso.
Ejemplo2: Optimizamos el acceso a rs.Fields:
from win32com.client import Dispatch
e=Dispatch("DAO.DBEngine.35")
db=e.OpenDatabase("c:/kk.mdb")
rs=db.OpenRecordset("SELECT * FROM kk")
from time import time
flds=rs.Fields # atencion a esto
t=time()
for i in range(100000):
rs.AddNew()
flds("Id").Value=i # acceso ahora mediante flds
flds("Nombre").Value="kkkkkk"
rs.Update()
print "tiempo: %s" % (time()-t)
db.Close()
100.000 registros, aprox. 30s: No está mal, nos ahoramos 16 segundos.
Sin embargo podemos ligar directamente los campos a una variable, como lo
hace Access / VisualBasic internamente:
from win32com.client import Dispatch
e=Dispatch("DAO.DBEngine.35")
db=e.OpenDatabase("c:/kk.mdb")
rs=db.OpenRecordset("SELECT * FROM kk")
from time import time
flds=rs.Fields
id,nombre=flds("Id"),flds("Nombre") # ligamos directamente
t=time()
for i in range(100000):
rs.AddNew()
id.Value,nombre.Value=i,"kkkkkk" # acceso directo a los campos
rs.Update()
print "tiempo: %s" % (time()-t)
db.Close()
100.000 registros: aprox: 12s. No está nada mal, hemos reducido de los 46
iniciales a 12, casi una cuarta parte.
Optimizando el acceso a los métodos (rs.AddNew y rs.Update), se obtiene una
ligera mejora de medio segundo. Creo que no merece la pena.
He probado esto también con transacción pero no mejora. Python.Com realiza
detrás de los escenarios conversiones y validaciones y quizá no se pueda
mejorar estos tiempos sustancialmente. El mismo ejemplo me tarda desde
Access unos 6 segundos.
>Bajo estas condiciones no puedo sustituir mis sistemas en VB + access
>por otro más lento. Necesito que al menos sea igual de eficiente.
Ahora bien, no creo que sea muy habitual que tengas que insertar 100.000
registros. Más bien, tienes que leer. Si son aplicaciones de gestión, puede
haber menos del 5% de sentencias de actualización. Se realizan constamente
búsquedas.Existe una función GetRows que es increíblemente rápida en obtener
datos, pero devuelve el resultado un array[columna][fila] (justo al revés de
lo convencional) y que tienes que dimensionar si los resultados son grandes.
Si utilizas Postgres, que es más lento porque es más completo, existe un
método para realizar una inserción rápida (sin comprobación de datos) que es
sustancialmente más rápido que muchos INSERTs, pero sigue siendo aprox 3
veces más lento que Access. (Access es realmente muy rápida, especialmente
con pocos clientes. Con unos cuantos clientes en red (10), se empieza a
ralentizar considerablemente.)
>Si alguien tiene programas de test de rendimiento de bases de datos,
>pede echarme una mano ?. Con qué otra base de datos puedo mejorar estos
>rendimientos. Sobre todo teniendo en cuenta que puede que tenga de ser
>instalada en Windows 98 de forma local, es decir; nada de servidores de
>datos.
Estos rendimientos son normalmente suficientes para hacer aplicaciones de
gestión, a excepción de aplicaciones OLAP donde necesitas bastante
rendimiento para el análisis de datos. En este caso, quizá sea mejor usar
PyTables (como propone Francesc). Puedes probar SQLite, que yo todavía no he
probado.
>Mis aplicaciones necesitan un acceso a base de datos muy, pero que muy
>rápido y poder trabajar con millones de registros.
¿Sin servidor de base de datos? ¿Mono-puesto? ¿A qué se van a dedicar estas
aplicaciones?
Erny
Más información sobre la lista de distribución Python-es