薄荷因為嫌他的 blog 速度太慢,轉而尋求其他 database back-end 的方案,比較MySQLPostgreSQLBerkeley DB 以及 SQLite 等四種解決方案。他的測試結果是:

  • MySQL: 3 min 17 sec
  • PostgreSQL: 3 min 50 sec
  • Berkeley DB: 4 min 32 sec
  • SQLite: 4 min 36 sec

我也曾經訝異於,宣稱比 MySQL 快上一籌的 SQLite,竟然會輸給 MySQL。後來搜尋文件與實驗後,才曉得,如果把 SQLite 的 sychronization (transaction) 功能關掉的話,SQLite 就可以在速度上領先 MySQL。

原理很簡單,Berkeley DB 和 SQLite 這種 file-based 資料庫,為了要因應 multi process 的環境,只好使用 file lock 來處理 concurrent access 的需求。也因此必須每次都 rebuild cache。而 MySQL、PostgreSQL 這類 client/server-based 資料庫,統一由一個 server process 管理 data files,可以直接在記憶體裡處理 concurrent access,不需要重新 rebuild cache,自然速度快很多。

像 rebuild all pages 這類大型的操作,如果 application 可以把 SQLite 的 transaction 功能關掉,或僅用一個 transaction 貫串全場的話,SQLite 的效能會呈指數倍大幅提昇。

我之前的經驗是,約數千個 INSERT 指令,如果每個 INSERT 指令一個 transaction 的話,SQLite 要花上數分鐘,但如果所有 INSERT 指令使用同一個 transaction 的話,則不到數秒鐘即可完成。以中、小流量的 Movable Type 網站來看,應該可以改寫成整個 rebuild all pages 共同使用同一個 transaction 來解決速度的問題。

所以,如果好好寫 SQLite 應用程式的話,SQLite 應用程式應該要比 MySQL 快,且整體的 overhead 比起要跑一個獨立 server 的 MySQL 要小非常多,僅佔 300k 的 binary size。但缺點就是,scability 不夠,如果有大型或超大型的需求的話,SQLite 就不適用了。不過這也不是身為殺雞刀的 SQLite 打算解決的問題就是了。