https://www.sqlite.org/speed.html 做了SQLite、MySQL和PostgreSQL的速度比较,使用的数据库版本比较老,但是测试方法依旧颇有意义。

小结
我们进行了一系列的测试来衡量SQLite 2.7.6、PostgreSQL 7.1.3和MySQL 3.23.41的相对性能。以下是从这些实验中得出的一般结论:
- SQLite 2.7.6比RedHat 7.2上默认安装的PostgreSQL 7.1.3在大多数常用操作上要快得多(有时快10或20倍)。
- 在大多数常见操作中,SQLite 2.7.6通常比MySQL 3.23.41快(有时快两倍以上)。
- SQLite执行CREATE INDEX或DROP TABLE的速度不如其他数据库。但影响不大,因为这些都是不常见操作。
- 将多个操作组合成事务时SQLite的工作效果最好。
测试说明:
- 不涉及多用户性能或涉及多个连接和子查询的复杂查询的优化。
- 在相对较小(大约14兆字节)的数据库上进行的。
测试环境
用于这些测试的平台是一台1.6GHz的Athlon,有1GB的内存和一个IDE磁盘驱动器。操作系统是RedHat Linux 7.2,stock内核。
使用的PostgreSQL和MySQL服务器是RedHat 7.2上默认提供的(PostgreSQL版本7.1.3和MySQL版本3.23.41)。特别注意的是,RedHat 7.2上的默认MySQL配置不支持事务。不支持事务给了MySQL很大的速度优势,但SQLite在大多数测试中仍然能够领先。
RedHat 7.3中的默认PostgreSQL配置太保守(它是为在8MB内存的机器上工作而设计的),通过配置调整,可以使PostgreSQL运行得快得多。Matt Sergeant报告说,他已经调整了他的PostgreSQL安装,结果显示,PostgreSQL和MySQL的运行速度基本相同。他对SQLite进行了测试,其配置与网站上出现的相同。它是用-O6优化和-DNDEBUG=1开关编译的,该开关禁用了SQLite代码中的许多 "assert() "语句。-DNDEBUG=1编译器选项使SQLite的速度大约提高了一倍。
一个简单的Tcl脚本被用来生成和运行所有的测试。这个Tcl脚本的副本可以在SQLite源代码树中的tools/speedtest.tcl文件中找到。

测试
测试1:1000个INSERT
- 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的完成。
测试2:事务中的25000个INSERT
- 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都快得多。
测试3:25000次INSERT到有索引的表中
- 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),但其总体速度仍较好。
测试4:100个没有索引的SELECT
[code]BEGIN;SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b=100 AND b=9800 AND b=9900 AND b=0 AND b=100 AND b=200 AND b=499700 AND b=499800 AND b=499900 AND b=0 AND a=10 AND a=9980 AND a=9990 AND a10 AND a |