关系型数据库速度比较(性能基准测试)及python实现

打印 上一主题 下一主题

主题 866|帖子 866|积分 2608

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
  1. CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));
  2. INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');
  3. INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');
  4. ... 995 lines omitted
  5. INSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');
  6. INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');
  7. INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');
复制代码

  • 结果:
  1. | PostgreSQL:            | 4.373  |
  2. | ---------------------- | ------ |
  3. | MySQL:                 | 0.114  |
  4. | SQLite 2.7.6:          | 13.061 |
  5. | SQLite 2.7.6 (nosync): | 0.223  |
复制代码
因为它没有中央服务器来协调访问,所以SQLite必须为每个事务关闭和重新打开数据库文件,从而使其缓存失效。在这个测试中,每个SQL语句都是一个单独的事务,所以数据库文件必须被打开和关闭,缓存必须被刷新1000次。尽管这样,SQLite的异步版本仍然几乎和MySQL一样快。然而,请注意同步版本的速度要慢得多。SQLite在每个同步事务之后调用fsync(),以确保所有数据在继续之前安全地在磁盘表面。在同步测试的13秒中,SQLite大部分时间都在闲置,等待磁盘I/O的完成。
测试2:事务中的25000个INSERT
  1. BEGIN;
  2. CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));
  3. INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two');
  4. ... 24997 lines omitted
  5. INSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine');
  6. INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six');
  7. COMMIT;
复制代码

  • 结果:
  1. | PostgreSQL:            | 4.900 |
  2. | ---------------------- | ----- |
  3. | MySQL:                 | 2.184 |
  4. | SQLite 2.7.6:          | 0.914 |
  5. | SQLite 2.7.6 (nosync): | 0.757 |
复制代码
当所有的INSERT被放在事务中时,SQLite不再需要关闭和重新打开数据库,不需要做任何fsync(),SQLite比PostgreSQL和MySQL都快得多。
测试3:25000次INSERT到有索引的表中
  1. BEGIN;
  2. CREATE TABLE t3(a INTEGER, b INTEGER, c VARCHAR(100));
  3. CREATE INDEX i3 ON t3(c);
  4. ... 24998 lines omitted
  5. INSERT INTO t3 VALUES(24999,88509,'eighty eight thousand five hundred nine');
  6. INSERT INTO t3 VALUES(25000,84791,'eighty four thousand seven hundred ninety one');
  7. COMMIT;
复制代码

  • 结果:
  1. | PostgreSQL:            | 8.175 |
  2. | ---------------------- | ----- |
  3. | MySQL:                 | 3.197 |
  4. | SQLite 2.7.6:          | 1.555 |
  5. | 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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

篮之新喜

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表