Как быстро SQLite по сравнению с Microsoft Access MDB?
В настоящее время я думаю о замене использования баз данных Microsoft Jet MDB в однопользовательском приложении .NET C# Windows Forms базой данных SQlite.
моя цель-снизить требования к установке, такие как драйверы реактивных двигателей и некоторые неприятные ошибки, когда реактивная установка была повреждена (у нас есть клиенты, время от времени сообщающие об этих ошибках).
мой вопрос относительно производительности:
есть ли какие-либо контрольные показатели там, сравнивая MDB и SQLite на довольно небольших наборах данных?
или есть какие-либо разработчики, которые уже сделали этот шаг и могут рассказать некоторые истории из своего собственного опыта?
(я гуглю часами без успеха)
обновление
хотя база данных не содержит это многие записи и таблицы, я думаю, производительность по-прежнему является проблемой, так как данные доступны довольно часто.
приложение представляет собой так называемую "настольную систему CMS", которая отображает HTML-страницы; во время рендеринга осуществляется доступ к довольно большому количеству данных и выполняется множество SQL-запросов.
обновление 2
нашел документация что указывает на некоторые сравнения скорости, к сожалению, не с MDB, насколько я могу видеть.
обновление 3
по запросу, некоторые цифры:
- ок. 30 таблиц в базе данных.
- большинство таблиц с гораздо ниже 100 записей.
- ок. 5 таблиц с Обычно нескольких 100 до нескольких тысяч записей.
- большой файл MDB будет около 60 МБ.
обновление 4
просто перефразировать: я не наличие каких-либо проблем с производительностью с текущей реализацией MDB. Я задаю этот вопрос, чтобы получить ощущение, будет ли производительность равна (или лучше) при использовании SQLite вместо MDB.
4 ответов
более 4 лет спустя я действительно сделал небольшой (возможно, несколько наивный) тест сравнения производительности между MDB и SQLite.
Я также добавил несколько баз данных.
Datebases я проверил
- SQL Server Express 2014 на том же локальном ПК и локальном SSD-диске, что и тестовое приложение.
- SQL Server Express 2014 на сервере в гигабитной локальной сети.
- SQL Server Compact (CE) на том же локальном ПК и локальный SSD-накопитель в качестве тестового приложения.
- Microsoft Access MDB / Jet на том же локальном ПК и локальном SSD-диске, что и тестовое приложение.
- Microsoft SQLite на том же локальном ПК и локальном SSD-диске, что и тестовое приложение.
- Microsoft VistaDB 5 на том же локальном ПК и локальном SSD-диске, что и тестовое приложение.
С некоторые базы данных не поддерживают связи объединения, я сделал два теста:
- один тест с закрытием соединения как можно скорее через
using
блок. - еще один тест с всегда открытым подключением к каждой базе данных в течение всего срока службы приложения
результаты тестирования при немедленном закрытии соединений
- SQL Express, работающий локально, был самым быстрым.
- SQL Express в нашей локальной сети был на второй позиции.
- среда SQL Compact Edition (CE) был намного быстрее, чем SQLite и Jet/MDB.
- Jet / MDB был немного быстрее, чем SQLite и намного медленнее, чем SQL CE.
- SQLite был немного медленнее, чем Jet/MDB.
- VistaDB 5 был на базе медленным в мой тест.
результаты тестирования при сохранении соединений открытыми
результаты довольно похожи на результаты при немедленном закрытии соединения.
относительно друг друга порядок от самого быстрого к самому медленному не менялся. Некоторые базы данных без фактического пула соединений значительно улучшили свою абсолютную производительность.
- SQL Express, работающий локально, был самым быстрым.
- SQL Express в нашей локальной сети был на второй позиции.
- SQL Compact Edition (CE) был намного быстрее, чем SQLite и Jet/MDB.
- Jet / MDB был немного быстрее, чем SQLite и гораздо медленнее, чем SQL CE.
- SQLite был немного медленнее, чем Jet/MDB.
- VistaDB 5 был на базе медленным в мой тест.
подробный вывод my тест приложения при немедленном закрытии соединений
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
подробный вывод my тест приложения при выполнении подключения
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
в случае, если вы решите провести собственное тестирование, я предлагаю эту процедуру для экспорта таблиц Jet в CSV-файлы. Затем вы можете импортировать их в свою базу данных 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
на самом деле, я не уверен, что вы действительно задаете правильный вопрос здесь.
Мне кажется, что вы ищете решение, меняя свои инструменты, а не меняя свой дизайн и свои подходы. Фактически, двигатель access jet существенно быстрее, чем что-то вроде oracle, mySQL или SQL server для большинства операций. Причина в том, что эти другие системы-огромная масса серверных систем, которые имеют сокет-соединения с сервером. Они имеют слои обработка транзакций. Существует, вероятно, 500 дополнительных уровней программного обеспечения и систем между вами и фактическими данными, которые находятся на жестком диске.
сравните это с доступом, который по существу является программой в процессе (не как запущенная служба). Вы не подключаетесь к файлам данных доступа через некоторое соединение TCP / IP, как вы делаете с серверными системами (на самом деле большинство этих серверных систем заставляют вас подключаться через и сетевой уровень, даже на вашем локальном компьютере и меньше вы используете подключение к локальной памяти, предполагая, что эта опция доступна).
JET (Access database engine) не является сервисом, а просто соскребает файл с жесткого диска и отображает результаты. Это соскабливание данных с диска происходит с той же скоростью, что и oracle или SQL server и все остальные системы (мы предполагаем ту же машину и оборудование здесь ). Тем не менее, эти другие системы все еще имеют еще 500, возможно, даже 1000 дополнительных уровней кода и программного обеспечения и Сетевые подключения и огромное количество thngs, таких как безопасность пользователей и т. д. Все это существенно замедляет процесс получения данных на диске большими объемами.
теперь, конечно, если вы говорите о подключении по какой-либо сети, то эти серверные системы лучше, потому что вы хотите, чтобы вся обработка и все, что majic произойдет, прежде чем какие-либо данные начнут течь по сетевой трубе.
однако в вашем случае, сервер и машина это одно и то же. Поэтому имеет смысл полностью исключить массу огромного контекста из тысяч дополнительных слоев программного обеспечения. Как я уже отмечал, и эти типы сценариев, jet может быть 50% или даже удвоить скорость серверных систем, таких как MySql или Oracle.
доступ может присоединяться, классифицироваться и суммироваться для 150 000 записей в течение секунды, и это с несколькими таблицами.
теперь с другой стороны, в любой из этих систем, обычно большие накладные расходы заключаются в том, чтобы открыть соединение с определенной таблицей. Фактически, время, необходимое для открытия таблицы, составляет около 30 000 записей для передачи. Таким образом, это означает, что вы хотите убедиться, что ваш код и использование этих таблиц не открывают новую таблицу (особенно в некотором типе цикла кода. Другими словами, даже в местах многократного выполнения команды insert SQL вам намного лучше открыть набор записей, а затем сделать вставки таким образом, как тогда вы больше не использовать команды SQL, и для каждой вставки строки вы не выполняете отдельный синтаксический анализ текста в этом sql (это может дать вам около 100 раз увеличить производительность при использовании access таким образом – другими словами, часто цитируемый совет здесь заключается в том, что использование команд SQL быстрее, чем открытие набора записей, совершенно неверно).
что это значит, если вы испытываете какое-то замедление здесь, я бы посмотрел на ваш код и проекты и гарантировал, что запись наборы данных и наборы данных не открываются и не закрываются повторно. Вы не должны испытывать какой-либо заметной задержки в операциях данных, учитывая крошечный размер файлов, которые вы упоминаете здесь.
чтобы быть справедливым, sqlLITE также (я считаю) в процессе не серверная версия MySql, и большинство преимуществ, указанных выше, также будут применяться. Но опять же, ваша горлышко бутылки не будет сильно отличаться в каждом случае, и поэтому мы вернемся к вопросам desing здесь.
другими словами, вы лаете на неправильное дерево, и разработчик, который ищет изменения в своих инструментах для исправления производительности, просто ищет исправление, обвиняя инструменты, когда в большинстве случаев проблема заключается в принятых проектах.
Jet 4.0, DAO, MDAC и ADO были включены в состав ОС Windows с Windows 2000. Таким образом, нет необходимости распространять какие-либо реактивные "драйверы" с вашим приложением.