Числа здесь стали бессмысленными. Эта страница была сохранена только как исторический экспонат.
Ряд тестов был запущен, чтобы измерить относительный уровень SQLite 2.7.6, PostgreSQL 7.1.3 и MySQL 3.23.41. Следующее это общие выводы, сделанные из этих экспериментов:
SQLite 2.7.6 значительно быстрее (иногда целых в 10 или 20 раз быстрее), чем установка PostgreSQL 7.1.3 по умолчанию на RedHat 7.2 для наиболее распространенных операций.
SQLite 2.7.6 часто быстрее (иногда более двух раз), чем MySQL 3.23.41 для наиболее распространенных операций.
SQLite не выполняет CREATE INDEX или DROP TABLE с такой скоростью, как другие базы данных. Но это не рассматривается как проблема, потому что это редкие операции.
SQLite работает лучше всего, если вы собираете в группу многократные операции в единственную транзакцию.
Результаты, представленные здесь, идут со следующими оговорками:
Эти тесты не попытались измерить многопользовательский уровень или оптимизацию сложных запросов, включающих многократные соединения и подзапросы.
Эти тесты идут на относительно маленькой базе данных (на приблизительно 14 мегабайт). Они не показывают, как хорошо ядра базы данных масштабируются к большим данным.
Платформой, используемой для этих тестов, является 1.6GHz Athlon с 1GB памяти и дисководом IDE. Операционная система RedHat Linux 7.2.
Серверы PostgreSQL и MySQL были поставлены по умолчанию на RedHat 7.2 (версия 7.1.3 PostgreSQL и версия 3.23.41 MySQL). Никакое усилие не было приложено, чтобы настроить эти СУБД. Отметьте в особенности, что конфигурация MySQL на RedHat 7.2 по умолчанию не поддерживает транзакции. Необходимость поддержать транзакции дает MySQL большое преимущество скорости, но SQLite все еще в состоянии держаться в отрыве на большинстве тестов.
Мне говорят, что конфигурация PostgreSQL по умолчанию в RedHat 7.3 излишне консервативна (это разработано, чтобы работать с машиной с 8 МБ RAM), и PostgreSQL мог бы работать намного быстрее с некоторой хорошей настройкой конфигурации. Matt Sergeant сообщает, что настроил свою установку PostgreSQL и запустил повторно тесты, показанные ниже. Его результаты показывают что PostgreSQL и MySQL работают на приблизительно той же самой скорости. Для результатов посмотрите
Obsolete URL: http://www.sergeant.org/sqlite_vs_pgsync.html
SQLite был проверен в той же самой конфигурации, как на веб-сайте. Это было собрано с оптимизацией -O6 и -DNDEBUG=1, который отключает многие "assert()" в коде SQLite. Параметр -DNDEBUG=1 примерно удваивает скорость SQLite.
Все тесты проводятся на одинаковой в других отношениях машине. Простой скрипт Tcl использовался, чтобы произвести и запустить все тесты. Копия этого скрипта Tcl может быть найдена в исходном дереве SQLite в файле tools/speedtest.tcl.
Времена, о которых сообщают относительно всех тестов, представляют время настенных часов в секундах. О двух отдельных временных значениях сообщают для SQLite. Первое для SQLite в конфигурации по умолчанию с включенной полной дисковой синхронизацией. С включенной синхронизацией SQLite выполняет системный вызов fsync() (или эквивалент) в ключевых пунктах, чтобы удостовериться, что критические данные были на самом деле написаны на диск. Синхронизация необходима, чтобы гарантировать целостность базы данных, если операционная система терпит крах или питание компьютера отключается неожиданно посреди обновления базы данных. Второй раз, о котором сообщают для SQLite, это когда синхронизация выключена. С выключенной синхронизацией SQLite иногда намного быстрее, но есть риск, что катастрофа операционной системы или неожиданный перебой в питании могли повредить базу данных. Вообще говоря, синхронные времена SQLite для сравнения с PostgreSQL (который также синхронен), и асинхронные времена SQLite для сравнения с асинхронным MySQL.
CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));
INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');
INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');
... 995 lines omitted
INSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');
INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');
INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');
PostgreSQL: | 4.373 |
MySQL: | 0.114 |
SQLite 2.7.6: | 13.061 |
SQLite 2.7.6 (nosync): | 0.223 |
Поскольку у этого нет центрального сервера, чтобы скоординировать доступ, SQLite должен закрыть и вновь открыть файл базы данных, и таким образом лишить законной силы свой кэш для каждой транзакции. В этом тесте каждый SQL-оператор это отдельная транзакция, таким образом, файл базы данных должен быть открыт и закрыт, и кэш должен сброситься 1000 раз. Несмотря на это, асинхронная версия SQLite все еще работает почти с такой же скоростью, как MySQL. Заметьте, насколько медленнее синхронная версия, как бы то ни было. SQLite вызывает fsync() после каждой синхронной транзакции, чтобы удостовериться, что все данные находятся безопасно на диске перед продолжением. В течение большинства этих 13 секунд в синхронном тесте SQLite простаивал, ожидая I/O на диске.
BEGIN;
CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));
INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two');
... 24997 lines omitted
INSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine');
INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six');
COMMIT;
PostgreSQL: | 4.900 |
MySQL: | 2.184 |
SQLite 2.7.6: | 0.914 |
SQLite 2.7.6 (nosync): | 0.757 |
Когда все INSERT помещаются в транзакцию, SQLite больше не должен закрывать и вновь открывать базу данных или лишать законной силы свой кэш между каждым запросом. Это также не должно делать никакого fsync() до самого конца. Когда не сковано таким образом, SQLite намного быстрее, чем любой PostgreSQL и MySQL.
BEGIN;
CREATE TABLE t3(a INTEGER, b INTEGER, c VARCHAR(100));
CREATE INDEX i3 ON t3(c);
... 24998 lines omitted
INSERT INTO t3 VALUES(24999,88509,'eighty eight thousand five hundred nine');
INSERT INTO t3 VALUES(25000,84791,'eighty four thousand seven hundred ninety one');
COMMIT;
PostgreSQL: | 8.175 |
MySQL: | 3.197 |
SQLite 2.7.6: | 1.555 |
SQLite 2.7.6 (nosync): | 1.402 |
Были отчеты, что SQLite не работал хорошо на индексируемой таблице. Этот тест был недавно добавлен, чтобы опровергнуть те слухи. Верно, что SQLite не так быстр при создании новых элементов индекса как другие СУБД (см. ниже тест 6), но его общая скорость еще лучше.
BEGIN;
SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b<1000;
SELECT count(*), avg(b) FROM t2 WHERE b>=100 AND b<1100;
... 96 lines omitted
SELECT count(*), avg(b) FROM t2 WHERE b>=9800 AND b<10800;
SELECT count(*), avg(b) FROM t2 WHERE b>=9900 AND b<10900;
COMMIT;
PostgreSQL: | 3.629 |
MySQL: | 2.760 |
SQLite 2.7.6: | 2.494 |
SQLite 2.7.6 (nosync): | 2.526 |
Этот тест делает 100 запросов на 25000 записей таблицы без индекса, таким образом требуя полного сканирования таблицы. Предыдущие версии SQLite раньше были медленнее, чем PostgreSQL и MySQL на этом тесте, но недавние улучшения увеличили скорость так, чтобы это было самым быстрым из группы.
BEGIN;
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one%';
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%two%';
... 96 lines omitted
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%ninety nine%';
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one hundred%';
COMMIT;
PostgreSQL: | 13.409 |
MySQL: | 4.640 |
SQLite 2.7.6: | 3.362 |
SQLite 2.7.6 (nosync): | 3.372 |
Этот тест все еще делает 100 полных сканирований таблицы, но он использует сравнения строк вместо числовых сравнений. SQLite более чем в три раза быстрее, чем PostgreSQL здесь и приблизительно на 30% быстрее, чем MySQL.
CREATE INDEX i2a ON t2(a);
CREATE INDEX i2b ON t2(b);
PostgreSQL: | 0.381 |
MySQL: | 0.318 |
SQLite 2.7.6: | 0.777 |
SQLite 2.7.6 (nosync): | 0.659 |
SQLite медленнее при создании новых индексов. Это не огромная проблема (так как новые индексы не создаются очень часто), но это что-то, с чем надо работать. Хотелось бы надеяться, будущие версии SQLite добьются большего успеха здесь.
SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b<100;
SELECT count(*), avg(b) FROM t2 WHERE b>=100 AND b<200;
SELECT count(*), avg(b) FROM t2 WHERE b>=200 AND b<300;
... 4994 lines omitted
SELECT count(*), avg(b) FROM t2 WHERE b>=499700 AND b<499800;
SELECT count(*), avg(b) FROM t2 WHERE b>=499800 AND b<499900;
SELECT count(*), avg(b) FROM t2 WHERE b>=499900 AND b<500000;
PostgreSQL: | 4.614 |
MySQL: | 1.270 |
SQLite 2.7.6: | 1.121 |
SQLite 2.7.6 (nosync): | 1.162 |
Все три ядра базы данных работают быстрее, когда у них есть индексы. Но SQLite является все еще самым быстрым.
BEGIN;
UPDATE t1 SET b=b*2 WHERE a>=0 AND a<10;
UPDATE t1 SET b=b*2 WHERE a>=10 AND a<20;
... 996 lines omitted
UPDATE t1 SET b=b*2 WHERE a>=9980 AND a<9990;
UPDATE t1 SET b=b*2 WHERE a>=9990 AND a<10000;
COMMIT;
PostgreSQL: | 1.739 |
MySQL: | 8.410 |
SQLite 2.7.6: | 0.637 |
SQLite 2.7.6 (nosync): | 0.638 |
Для этого конкретного теста UPDATE MySQL последовательно в пять или десять раз медленнее, чем PostgreSQL и SQLite. Я не знаю почему. MySQL обычно очень быстр. Возможно, эта проблема была решена в более поздних версиях MySQL.
BEGIN;
UPDATE t2 SET b=468026 WHERE a=1;
UPDATE t2 SET b=121928 WHERE a=2;
... 24996 lines omitted
UPDATE t2 SET b=35065 WHERE a=24999;
UPDATE t2 SET b=347393 WHERE a=25000;
COMMIT;
PostgreSQL: | 18.797 |
MySQL: | 8.134 |
SQLite 2.7.6: | 3.520 |
SQLite 2.7.6 (nosync): | 3.104 |
Уже версия SQLite 2.7.0 работала приблизительно с той же самой скоростью, как MySQL на этом тесте. Но недавняя оптимизация SQLite более чем удвоила скорость UPDATE.
BEGIN;
UPDATE t2 SET c='one hundred forty eight thousand three hundred eighty two' WHERE a=1;
UPDATE t2 SET c='three hundred sixty six thousand five hundred two' WHERE a=2;
... 24996 lines omitted
UPDATE t2 SET c='three hundred eighty three thousand ninety nine' WHERE a=24999;
UPDATE t2 SET c='two hundred fifty six thousand eight hundred thirty' WHERE a=25000;
COMMIT;
PostgreSQL: | 48.133 |
MySQL: | 6.982 |
SQLite 2.7.6: | 2.408 |
SQLite 2.7.6 (nosync): | 1.725 |
Здесь снова версия SQLite 2.7.0 раньше работала на приблизительно той же самой скорости, как MySQL. Но теперь версия 2.7.6 более чем в два раза быстрее, чем MySQL и более чем в двадцать раз быстрее, чем PostgreSQL.
PostgreSQL начал побеждать на этом тесте. Хорошо осведомленный администратор мог бы быть в состоянии заставить PostgreSQL работать намного быстрее, настраивая сервер.
BEGIN;
INSERT INTO t1 SELECT b,a,c FROM t2;
INSERT INTO t2 SELECT b,a,c FROM t1;
COMMIT;
PostgreSQL: | 61.364 |
MySQL: | 1.537 |
SQLite 2.7.6: | 2.787 |
SQLite 2.7.6 (nosync): | 1.599 |
Асинхронный SQLite чуть медленнее, чем MySQL на этом тесте. MySQL, кажется, особенно владеет мастерством INSERT...SELECT. PostgreSQL все еще побеждает, большая часть этой 61 секунды, которые он использовал, были потрачены, ожидая I/O диска.
DELETE FROM t2 WHERE c LIKE '%fifty%';
PostgreSQL: | 1.509 |
MySQL: | 0.975 |
SQLite 2.7.6: | 4.004 |
SQLite 2.7.6 (nosync): | 0.560 |
Синхронная версия SQLite является самой медленной из группы в этом тесте, но асинхронная версия является самой быстрой. Различие в дополнительном времени, чтобы выполнить fsync().
DELETE FROM t2 WHERE a>10 AND a<20000;
PostgreSQL: | 1.316 |
MySQL: | 2.262 |
SQLite 2.7.6: | 2.068 |
SQLite 2.7.6 (nosync): | 0.752 |
Этот тест значительный, потому что это один из тех, где PostgreSQL быстрее, чем MySQL. Асинхронный SQLite, однако, быстрее.
INSERT INTO t2 SELECT * FROM t1;
PostgreSQL: | 13.168 |
MySQL: | 1.815 |
SQLite 2.7.6: | 3.210 |
SQLite 2.7.6 (nosync): | 1.485 |
Некоторые более старые версии SQLite (до версии 2.4.0) показали бы уменьшающуюся производительность после последовательности DELETE, сопровождаемой новым INSERT. Как этот тест показывает, проблема была решена.
BEGIN;
DELETE FROM t1;
INSERT INTO t1 VALUES(1,10719,'ten thousand seven hundred nineteen');
... 11997 lines omitted
INSERT INTO t1 VALUES(11999,72836,'seventy two thousand eight hundred thirty six');
INSERT INTO t1 VALUES(12000,64231,'sixty four thousand two hundred thirty one');
COMMIT;
PostgreSQL: | 4.556 |
MySQL: | 1.704 |
SQLite 2.7.6: | 0.618 |
SQLite 2.7.6 (nosync): | 0.406 |
SQLite очень хорош в выполнении INSERT в транзакции, которая, вероятно, объясняет, почему это настолько быстрее, чем другие базы данных в этом тесте.
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
PostgreSQL: | 0.135 |
MySQL: | 0.015 |
SQLite 2.7.6: | 0.939 |
SQLite 2.7.6 (nosync): | 0.254 |
SQLite медленнее, чем другие базы данных когда дело доходит до удаления таблиц. Это, вероятно потому что, когда SQLite удаляет таблицу, он должен пройти и стереть записи в файле базы данных, которые имеют дело с этой таблицей. MySQL и PostgreSQL, с другой стороны, используют отдельные файлы, чтобы представлять каждую таблицу, таким образом, они могут просто удалить файл, что намного быстрее.
С другой стороны удаление таблиц не является очень общей операцией поэтому, если SQLite работает немного дольше, это не рассматривается как большая проблема.