這裡的數字已無意義。此頁面僅作為歷史文物保留。
進行了一系列測試,以衡量 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 MB)上進行的。它們並未衡量資料庫引擎如何擴充到更大的問題。
用於這些測試的平台是配備 1GB 記憶體和 IDE 磁碟機的 1.6GHz Athlon。作業系統是具有庫存核心模組的 RedHat Linux 7.2。
所使用的 PostgreSQL 和 MySQL 伺服器是 RedHat 7.2 預設提供的。(PostgreSQL 版本 7.1.3 和 MySQL 版本 3.23.41。)並未嘗試調整這些引擎。特別注意的是,RedHat 7.2 上的預設 MySQL 組態不支援交易。無需支援交易讓 MySQL 獲得極大的速度優勢,但 SQLite 仍能在大多數測試中保持其優勢。
我聽說 RedHat 7.3 中的預設 PostgreSQL 組態過於保守(它設計用於在 8MB RAM 的機器上執行),而 PostgreSQL 只要經過一些專業的組態調整,就能執行得更快。Matt Sergeant 回報說他調整了他的 PostgreSQL 安裝,並重新執行以下所示的測試。他的結果顯示 PostgreSQL 和 MySQL 的執行速度大約相同。如需 Matt 的結果,請拜訪
已過時的網址:http://www.sergeant.org/sqlite_vs_pgsync.html
SQLite 在網站上顯示的相同組態中進行測試。它使用 -O6 最佳化編譯,並使用 -DNDEBUG=1 開關,這會停用 SQLite 程式碼中的許多「assert()」陳述式。-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,'七十五萬五千五百六十');
... 省略 995 行
INSERT INTO t1 VALUES(998,66289,'六十六萬二千二百八十九');
INSERT INTO t1 VALUES(999,24322,'二萬四千三百二十二');
INSERT INTO t1 VALUES(1000,94142,'九十四萬一千一百四十二');
PostgreSQL | 4.373 |
MySQL | 0.114 |
SQLite 2.7.6 | 13.061 |
SQLite 2.7.6 (nosync) | 0.223 |
由於 SQLite 沒有中央伺服器來協調存取,因此對於每個交易,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,'五萬九千六百七十二');
... 省略 24997 行
INSERT INTO t2 VALUES(24999,89569,'八萬九千五百六十九');
INSERT INTO t2 VALUES(25000,94666,'九十四萬六千六百六十六');
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 行
INSERT INTO t3 VALUES(24999,88509,'八萬八千五百零九');
INSERT INTO t3 VALUES(25000,84791,'八萬四千七百九十一');
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 行
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 |
此測試在沒有索引的 25000 個項目表格上執行 100 次查詢,因此需要進行全表掃描。舊版本的 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 行
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 快三倍以上,比 MySQL 快約 30%。
CREATE INDEX i2a ON t2(a);
在 t2(b) 上建立索引 i2b;
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 行
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 行
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 行
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 |
在 2.7.0 版本中,SQLite 在這個測試中的執行速度與 MySQL 差不多。但最近對 SQLite 的最佳化已將 UPDATE 速度提升了一倍以上。
BEGIN;
UPDATE t2 SET c='one hundred forty eight thousand three hundred eighty two' WHERE a=1;
UPDATE t2 SET c='三十六萬六千五百零二' WHERE a=2;
... 省略 24996 行
UPDATE t2 SET c='三十八萬三千零九十九' WHERE a=24999;
UPDATE t2 SET c='二十五萬六千八百三十' 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 版之前的版本)會在刪除動作後接著新插入動作後,顯示效能下降。如測試所示,此問題現已解決。
BEGIN;
DELETE FROM t1;
INSERT INTO t1 VALUES(1,10719,'一萬零七百一十九');
... 省略 11997 行
INSERT INTO t1 VALUES(11999,72836,'七萬二千八百三十六');
INSERT INTO t1 VALUES(12000,64231,'六萬四千二百三十一');
COMMIT;
PostgreSQL | 4.556 |
MySQL | 1.704 |
SQLite 2.7.6 | 0.618 |
SQLite 2.7.6 (nosync) | 0.406 |
SQLite 非常擅長在交易中進行插入,這可能是為什麼它在此測試中比其他資料庫快這麼多的原因。
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 花費較長的時間,這並不會被視為一個大問題。
此頁面最後修改於 2023-01-02 14:22:42 UTC