Saltar al contenido

¿Qué tan rápido es SQLite en comparación con Microsoft Access MDB?

Solución:

Más de 4 años después, hice una pequeña prueba de comparación de rendimiento (probablemente algo ingenua) entre MDB y SQLite.

También agregué más bases de datos.

Bases de datos que he probado

  • SQL Server Express 2014 en la misma PC local y unidad SSD local que la aplicación de prueba.
  • SQL Server Express 2014 en un servidor en una LAN gigabit.
  • SQL Server Compact (CE) en la misma PC local y unidad SSD local que la aplicación de prueba.
  • Microsoft Access MDB / Jet en la misma PC local y unidad SSD local que la aplicación de prueba.
  • Microsoft SQLite en la misma PC local y unidad SSD local que la aplicación de prueba.
  • Microsoft VistaDB 5 en la misma PC local y unidad SSD local que la aplicación de prueba.

Dado que algunas bases de datos no admiten la agrupación de conexiones, he realizado dos pruebas:

  1. Una prueba con cerrar la conexión lo antes posible a través de un using cuadra.
  2. Otra prueba con una conexión siempre abierta a cada base de datos durante toda la vida útil de la aplicación

Resultados de la prueba al cerrar las conexiones inmediatamente

  • SQL Express ejecutado localmente fue el más rápido.
  • SQL Express en nuestra red local estaba en segunda posición.
  • SQL Compact Edition (CE) fue mucho más rápido que SQLite y Jet / MDB.
  • Jet / MDB era un poco más rápido que SQLite y mucho más lento que SQL CE.
  • SQLite era un poco más lento que Jet / MDB.
  • VistaDB 5 fue la base de datos más lenta de mi prueba.

Resultados de la prueba al mantener las conexiones abiertas

Los resultados son bastante similares a los que se obtienen al cerrar una conexión inmediatamente.

Relativamente entre sí, el orden del más rápido al más lento no cambió. Algunas bases de datos sin una agrupación de conexiones real mejoraron bastante su rendimiento absoluto.

  • SQL Express ejecutado localmente fue el más rápido.
  • SQL Express en nuestra red local estaba en segunda posición.
  • SQL Compact Edition (CE) fue mucho más rápido que SQLite y Jet / MDB.
  • Jet / MDB era un poco más rápido que SQLite y mucho más lento que SQL CE.
  • SQLite era un poco más lento que Jet / MDB.
  • VistaDB 5 fue la base de datos más lenta de mi prueba.

Salida detallada de mi aplicación de prueba al cerrar las conexiones inmediatamente

1.: 1 x DELETE FROM Tabelle1 (Closing connections):
- SQL Express local : 00:00:00.1723705
- SQL Express remote: 00:00:00.2093229
- SQL CE            : 00:00:00.3141897
- MS Access         : 00:00:00.3854029
- SQLite            : 00:00:00.4639365
- VistaDB           : 00:00:00.9699047

2.: 1 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES (LOOPCTR, 'LOOPCTR') (Closing connections):
- SQL Express local : 00:00:00.0039836
- SQL Express remote: 00:00:00.0062002
- SQL CE            : 00:00:00.0432679
- MS Access         : 00:00:00.0817834
- SQLite            : 00:00:00.0933030
- VistaDB           : 00:00:00.1200426

3.: 10 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES (LOOPCTR, 'LOOPCTR') (Closing connections):
- SQL Express local : 00:00:00.0031593
- SQL Express remote: 00:00:00.0142514
- SQL CE            : 00:00:00.3724224
- MS Access         : 00:00:00.7474003
- SQLite            : 00:00:00.8818905
- VistaDB           : 00:00:00.9342783

4.: 100 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES (LOOPCTR, 'LOOPCTR') (Closing connections):
- SQL Express local : 00:00:00.0242817
- SQL Express remote: 00:00:00.1124771
- SQL CE            : 00:00:03.6239390
- MS Access         : 00:00:07.3752378
- SQLite            : 00:00:08.6489843
- VistaDB           : 00:00:09.0933903

5.: 1000 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES (LOOPCTR, 'LOOPCTR') (Closing connections):
- SQL Express local : 00:00:00.2735537
- SQL Express remote: 00:00:01.2657006
- SQL CE            : 00:00:36.2335727
- MS Access         : 00:01:13.8782439
- SQLite            : 00:01:27.1783328
- VistaDB           : 00:01:32.0760340

6.: 1 x SELECT * FROM Tabelle1 (Closing connections):
- SQL Express local : 00:00:00.0520670
- SQL Express remote: 00:00:00.0570562
- SQL CE            : 00:00:00.1026963
- MS Access         : 00:00:00.1646635
- SQLite            : 00:00:00.1785981
- VistaDB           : 00:00:00.2311263

7.: 10 x SELECT * FROM Tabelle1 (Closing connections):
- SQL Express local : 00:00:00.0183055
- SQL Express remote: 00:00:00.0501115
- SQL CE            : 00:00:00.3235680
- MS Access         : 00:00:00.7119203
- SQLite            : 00:00:00.7533361
- VistaDB           : 00:00:00.9804508

8.: 100 x SELECT * FROM Tabelle1 (Closing connections):
- SQL Express local : 00:00:00.1787837
- SQL Express remote: 00:00:00.4321814
- SQL CE            : 00:00:03.0401779
- MS Access         : 00:00:06.8338598
- SQLite            : 00:00:07.2000139
- VistaDB           : 00:00:09.1889217

9.: 1000 x SELECT * FROM Tabelle1 (Closing connections):
- SQL Express local : 00:00:01.6112566
- SQL Express remote: 00:00:03.9542611
- SQL CE            : 00:00:29.1209991
- MS Access         : 00:01:07.2309769
- SQLite            : 00:01:10.3167922
- VistaDB           : 00:01:31.4312770

10.: 1 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID ORDER BY a.ID (Closing connections):
- SQL Express local : 00:00:00.0029406
- SQL Express remote: 00:00:00.0088138
- SQL CE            : 00:00:00.0498847
- MS Access         : 00:00:00.0893892
- SQLite            : 00:00:00.0929506
- VistaDB           : 00:00:00.2575795

11.: 10 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID ORDER BY a.ID (Closing connections):
- SQL Express local : 00:00:00.0174026
- SQL Express remote: 00:00:00.0400797
- SQL CE            : 00:00:00.3408818
- MS Access         : 00:00:00.7314978
- SQLite            : 00:00:00.7653330
- VistaDB           : 00:00:01.9565675

12.: 100 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID ORDER BY a.ID (Closing connections):
- SQL Express local : 00:00:00.1565402
- SQL Express remote: 00:00:00.3787208
- SQL CE            : 00:00:03.3516629
- MS Access         : 00:00:07.2521126
- SQLite            : 00:00:07.5618047
- VistaDB           : 00:00:19.5181391

13.: 1000 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID ORDER BY a.ID (Closing connections):
- SQL Express local : 00:00:01.5686470
- SQL Express remote: 00:00:03.7414669
- SQL CE            : 00:00:35.3944204
- MS Access         : 00:01:14.6872377
- SQLite            : 00:01:17.9964955
- VistaDB           : 00:03:18.1902279

14.: 1 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID WHERE a.ID < 100 OR a.ID > 300 ORDER BY a.ID (Closing connections):
- SQL Express local : 00:00:00.0053295
- SQL Express remote: 00:00:00.0089722
- SQL CE            : 00:00:00.0395485
- MS Access         : 00:00:00.0797776
- SQLite            : 00:00:00.0833477
- VistaDB           : 00:00:00.2554930

15.: 10 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID WHERE a.ID < 100 OR a.ID > 300 ORDER BY a.ID (Closing connections):
- SQL Express local : 00:00:00.0168467
- SQL Express remote: 00:00:00.0552233
- SQL CE            : 00:00:00.3929877
- MS Access         : 00:00:00.7886399
- SQLite            : 00:00:00.8209904
- VistaDB           : 00:00:02.1248734

16.: 100 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID WHERE a.ID < 100 OR a.ID > 300 ORDER BY a.ID (Closing connections):
- SQL Express local : 00:00:00.1705345
- SQL Express remote: 00:00:00.3969228
- SQL CE            : 00:00:03.4886826
- MS Access         : 00:00:07.4564258
- SQLite            : 00:00:07.7828646
- VistaDB           : 00:00:20.4092926

17.: 1000 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID WHERE a.ID < 100 OR a.ID > 300 ORDER BY a.ID (Closing connections):
- SQL Express local : 00:00:01.6237424
- SQL Express remote: 00:00:03.9816212
- SQL CE            : 00:00:35.1441759
- MS Access         : 00:01:14.7739758
- SQLite            : 00:01:17.9477049
- VistaDB           : 00:03:24.0049633

Salida detallada de mi aplicación de prueba al mantener las conexiones abiertas

1.: 1 x DELETE FROM Tabelle1 (keeping connection open):
- SQL Express local : 00:00:00.0426930
- SQL Express remote: 00:00:00.0546357
- SQL CE            : 00:00:00.0786765
- MS Access         : 00:00:00.0909099
- SQLite            : 00:00:00.1101572
- VistaDB           : 00:00:00.4637726

2.: 1 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES (LOOPCTR, 'LOOPCTR') (keeping connection open):
- SQL Express local : 00:00:00.0030936
- SQL Express remote: 00:00:00.0051136
- SQL CE            : 00:00:00.0054226
- MS Access         : 00:00:00.0074847
- SQLite            : 00:00:00.0154474
- VistaDB           : 00:00:00.0373701

3.: 10 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES (LOOPCTR, 'LOOPCTR') (keeping connection open):
- SQL Express local : 00:00:00.0023271
- SQL Express remote: 00:00:00.0109913
- SQL CE            : 00:00:00.0119872
- MS Access         : 00:00:00.0152531
- SQLite            : 00:00:00.1131698
- VistaDB           : 00:00:00.1261859

4.: 100 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES (LOOPCTR, 'LOOPCTR') (keeping connection open):
- SQL Express local : 00:00:00.0201695
- SQL Express remote: 00:00:00.0888872
- SQL CE            : 00:00:00.0966017
- MS Access         : 00:00:00.1256167
- SQLite            : 00:00:01.3632978
- VistaDB           : 00:00:01.9422151

5.: 1000 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES (LOOPCTR, 'LOOPCTR') (keeping connection open):
- SQL Express local : 00:00:00.1693362
- SQL Express remote: 00:00:00.9181297
- SQL CE            : 00:00:01.0366334
- MS Access         : 00:00:01.2794199
- SQLite            : 00:00:13.9398816
- VistaDB           : 00:00:19.8319476

6.: 1 x SELECT * FROM Tabelle1 (keeping connection open):
- SQL Express local : 00:00:00.0481500
- SQL Express remote: 00:00:00.0507066
- SQL CE            : 00:00:00.0738698
- MS Access         : 00:00:00.0911707
- SQLite            : 00:00:00.1012425
- VistaDB           : 00:00:00.1515495

7.: 10 x SELECT * FROM Tabelle1 (keeping connection open):
- SQL Express local : 00:00:00.0157947
- SQL Express remote: 00:00:00.0692206
- SQL CE            : 00:00:00.0898558
- MS Access         : 00:00:00.1196514
- SQLite            : 00:00:00.1400944
- VistaDB           : 00:00:00.3227485

8.: 100 x SELECT * FROM Tabelle1 (keeping connection open):
- SQL Express local : 00:00:00.1517498
- SQL Express remote: 00:00:00.3399897
- SQL CE            : 00:00:00.5497382
- MS Access         : 00:00:00.8619646
- SQLite            : 00:00:01.0463369
- VistaDB           : 00:00:02.8607334

9.: 1000 x SELECT * FROM Tabelle1 (keeping connection open):
- SQL Express local : 00:00:01.5042900
- SQL Express remote: 00:00:03.8431985
- SQL CE            : 00:00:05.9075477
- MS Access         : 00:00:09.2642402
- SQLite            : 00:00:11.4427914
- VistaDB           : 00:00:30.8470936

10.: 1 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID ORDER BY a.ID (keeping connection open):
- SQL Express local : 00:00:00.0033803
- SQL Express remote: 00:00:00.0062499
- SQL CE            : 00:00:00.0141105
- MS Access         : 00:00:00.0188573
- SQLite            : 00:00:00.0208236
- VistaDB           : 00:00:00.1796513

11.: 10 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID ORDER BY a.ID (keeping connection open):
- SQL Express local : 00:00:00.0168644
- SQL Express remote: 00:00:00.0377185
- SQL CE            : 00:00:00.1121558
- MS Access         : 00:00:00.1599104
- SQLite            : 00:00:00.1799435
- VistaDB           : 00:00:01.4042534

12.: 100 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID ORDER BY a.ID (keeping connection open):
- SQL Express local : 00:00:00.1547275
- SQL Express remote: 00:00:00.3692526
- SQL CE            : 00:00:01.1215470
- MS Access         : 00:00:01.5577172
- SQLite            : 00:00:01.7519790
- VistaDB           : 00:00:14.5687575

13.: 1000 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID ORDER BY a.ID (keeping connection open):
- SQL Express local : 00:00:01.4992800
- SQL Express remote: 00:00:03.7601806
- SQL CE            : 00:00:11.1738426
- MS Access         : 00:00:15.8112902
- SQLite            : 00:00:17.8045042
- VistaDB           : 00:02:21.4492368

14.: 1 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID WHERE a.ID < 100 OR a.ID > 300 ORDER BY a.ID (keeping connection open):
- SQL Express local : 00:00:00.0048145
- SQL Express remote: 00:00:00.0076790
- SQL CE            : 00:00:00.0152074
- MS Access         : 00:00:00.0204568
- SQLite            : 00:00:00.0229056
- VistaDB           : 00:00:00.2091614

15.: 10 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID WHERE a.ID < 100 OR a.ID > 300 ORDER BY a.ID (keeping connection open):
- SQL Express local : 00:00:00.0156564
- SQL Express remote: 00:00:00.0377571
- SQL CE            : 00:00:00.1138433
- MS Access         : 00:00:00.1598932
- SQLite            : 00:00:00.1793267
- VistaDB           : 00:00:01.4667061

16.: 100 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID WHERE a.ID < 100 OR a.ID > 300 ORDER BY a.ID (keeping connection open):
- SQL Express local : 00:00:00.1512625
- SQL Express remote: 00:00:00.4658652
- SQL CE            : 00:00:01.2441809
- MS Access         : 00:00:01.7224126
- SQLite            : 00:00:01.9297231
- VistaDB           : 00:00:14.9351318

17.: 1000 x SELECT a.* FROM Tabelle1 a LEFT JOIN Tabelle1 b ON a.ID=b.ID WHERE a.ID < 100 OR a.ID > 300 ORDER BY a.ID (keeping connection open):
- SQL Express local : 00:00:01.5223833
- SQL Express remote: 00:00:03.9885174
- SQL CE            : 00:00:11.8356048
- MS Access         : 00:00:16.5977939
- SQLite            : 00:00:18.6504260
- VistaDB           : 00:02:26.0513056

Actualización 1, abril de 2019

Hice algunas pruebas comparando Microsoft Access MDB con LiteDB, una base de datos integrada para .NET.

Así que de nuevo, una comparación bastante ingenua, pero todavía quería tener una sensación.

Este código hace 1000 lecturas y escrituras y dio como resultado estos valores:

Access             of 1000 WRITE iterations took 00:00:39.6488351.
LiteDB             of 1000 WRITE iterations took 00:00:01.6596646.
LiteDB (in-memory) of 1000 WRITE iterations took 00:00:00.1617220.
Access             of 1000 READ  iterations took 00:00:48.8517302.
LiteDB             of 1000 READ  iterations took 00:00:00.0082401.
LiteDB (in-memory) of 1000 READ  iterations took 00:00:00.0097933.

Entonces, en mi escenario, LiteDB fue mucho más rápido que Access.

Actualización 2, abril de 2019

También ejecuté mi código original contra VistaDB 6 Beta 1 en comparación con VistaDB 5.

Tengo resultados de velocidad muy similares. La Beta de VistaDB 6 fue un poco más lenta en comparación con VistaDB 5, probablemente porque era una compilación de depuración.

Como conclusión, veo no Mejoras de rendimiento significativas en mi escenario entre VistaDB 5 y VistaDB 6 Beta 1. Tendré que intentarlo de nuevo con la versión final de VistaDB 6.

En caso de que decida hacer sus propias pruebas comparativas, le ofrezco este procedimiento para exportar sus tablas Jet a archivos CSV. Luego, puede importarlos a su base de datos SQLite.

Public Sub DumpTablesAsCsv()
    Dim db As DAO.Database
    Dim tdf As DAO.TableDef
    Dim strCsvFile As String
    Dim strFolder As String
    Dim strTable As String

    strFolder = CurrentProject.Path & Chr(92)
    Set db = CurrentDb
    For Each tdf In db.TableDefs
        strTable = tdf.Name
        If Not (strTable Like "MSys*" Or strTable Like "~*") Then
            strCsvFile = strFolder & strTable & ".csv"
            DoCmd.TransferText acExportDelim, , strTable, _
                strCsvFile, HasFieldNames:=True
        End If
    Next tdf
    Set tdf = Nothing
    Set db = Nothing
End Sub

De hecho, no estoy seguro de que estés haciendo la pregunta correcta aquí.

Me parece que está buscando una solución cambiando sus herramientas y no cambiando su diseño y sus enfoques. De hecho, el motor a reacción de acceso es sustancialmente más rápido que algo como un oráculo, mySQL o un servidor SQL para la mayoría de las operaciones. La razón es que esos otros sistemas son una gran masa de sistemas basados ​​en servidores que tienen conexiones de socket al servidor. Tienen capas de procesamiento de transacciones. Probablemente haya 500 capas adicionales de software y sistemas entre usted y los datos reales que residen en el disco duro.

Compare eso con el acceso, que es esencialmente un programa en proceso (no como un servicio en ejecución). No se conecta a los archivos de datos de Access a través de alguna conexión TCP / IP como lo hace con los sistemas basados ​​en servidor (de hecho, la mayoría de esos sistemas basados ​​en servidor lo obligan a conectarse a través de una capa de red, incluso en su máquina local y menos si usa una conexión de memoria, suponiendo que esa opción esté disponible).

JET (motor de base de datos de Access) no es un servicio, simplemente raspa el archivo del disco duro y muestra los resultados. Ese raspado de los datos de la unidad de disco ocurre a la misma velocidad que Oracle o SQL Server y todos esos otros sistemas (asumimos la misma máquina y hardware aquí). Sin embargo, esos otros sistemas todavía tienen otras 500, quizás incluso 1000 capas adicionales de código y software y conexiones de red y cantidades masivas de cosas como la seguridad del usuario, etc. Todas estas cosas ralentizan sustancialmente el acceso a los datos en la unidad de disco en grandes cantidades.

Ahora, por supuesto, si habla de una conexión a través de algún tipo de red, entonces esos sistemas basados ​​en servidor son mejores, porque desea que todo el procesamiento y todo eso ocurra ANTES de que los datos comiencen a fluir por la red.

Sin embargo, en su escenario, el servidor y la máquina son lo mismo. Por lo tanto, tiene mucho sentido eliminar la masa de contexto enorme de miles de capas adicionales de software. Como señalé, y en este tipo de escenarios, el jet puede ser del 50% o incluso el doble de la velocidad de los sistemas basados ​​en servidor como MySql u Oracle.

Access puede unirse, categorizar y totalizar inventariado para 150,000 registros en menos de un segundo, y eso con una combinación de varias tablas.

Ahora, por otro lado, en cualquiera de estos sistemas, por lo general, la gran sobrecarga es abrir una conexión a una mesa en particular. De hecho, el tiempo que lleva abrir una tabla es aproximadamente el costo de transferencia de 30.000 registros. Entonces, esto significa que desea asegurarse de que su código y el uso de estas tablas no abran innecesariamente una nueva tabla (especialmente en algún tipo de ciclo de código. En otras palabras, incluso en lugares donde se ejecuta repetidamente un comando de inserción un SQL, Es mucho mejor abrir un conjunto de registros y luego hacer inserciones de esa manera, ya que entonces ya no está usando comandos SQL, y para cada inserción de fila no está ejecutando un análisis por separado del texto en ese sql ( esto puede aumentar el rendimiento unas 100 veces al usar el acceso de esta manera; en otras palabras, el consejo que se cita a menudo aquí es que usar comandos SQL es más rápido que abrir un conjunto de registros, es completamente incorrecto).

Lo que esto significa es que, si está experimentando algún tipo de desaceleración aquí, miraré su código y diseños, y me aseguraré de que los conjuntos de registros y los conjuntos de datos no se abran y cierren repetidamente. No debería experimentar ningún tipo de retraso notable en sus operaciones de datos dado el pequeño tamaño de los archivos que menciona aquí.

Para ser justos, sqlLITE también es (creo) una edición en proceso no basada en servidor de MySql, y la mayoría de las ventajas señaladas anteriormente también se aplicarían. Pero, de nuevo, su cuello de botella no sería muy diferente en cada caso, por lo que volvemos a los problemas de diseño aquí.

En otras palabras, está ladrando al árbol equivocado, y un desarrollador que busca cambios en sus herramientas para corregir el rendimiento simplemente busca una solución culpando a las herramientas cuando en la mayoría de los casos el problema radica en los diseños adoptados.

Si te apasiona este mundo, eres capaz de dejar una sección acerca de qué le añadirías a este post.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *