DB全般をあまり知らないので、仕事上使っているPostgreSQL上で簡単なベンチマークをとる。
実行環境
- ASUS ROG Zephyrus GX502
- Ubuntu 20.04
- PostgreSQL 12.5
- SBCL 2.0.11
- Quicklisp 2020-12-20
- ASUS ROG Zephyrus GX502
参考文献
PostgresSQLの準備
https://www.postgresql.jp/document/12/html/tutorial-start.html ローカルにPostgresSQLをインストールする。
psqlからデータベースを作る。
createdb test
練習用ロールを作る。
CREATE USER "myuser" CREATEDB PASSWORD '1234';
cl-dbiでのアクセス
cl-dbiで対象dbに接続する。
(ql:quickload :cl-dbi) (defvar *connection* (dbi:connect :postgres :database-name "test" :username "myuser" :password "1234"))
実行用の関数を定義する。
(defun run (string &key params silent) (let ((query (dbi:execute (dbi:prepare *connection* string) params))) (unless silent (loop for row = (dbi:fetch query) while row do (pprint row)))))
テーブルを作る。
(time (run "CREATE TABLE bench1 (uuid varchar(36), int_data int, real_data real);"))
データを登録する。
(run "INSERT INTO bench1 VALUES (?, ?, ?);" :params (list (print-object (uuid:make-v4-uuid) nil) (random 100) (random 100.0)) :silent t)
1つデータを見る。
(run "SELECT * FROM bench1 LIMIT 1;" ) ;; (:|uuid| "9D9624B4-9275-4F67-8754-B8F27710D77C" :|int_data| 31 :|real_data| 31.218767)
データ数を見る。
(run "SELECT COUNT(*) FROM bench1;" ) ;; (:|count| 1000)
ベンチマーク用データ追加
ちょっとした問題として、SELECTのベンチマークをとるためにデータのINSERTを100万回くらい行おうとすると途中でheap exhaustedとなる。 どこかでメモリーリークがあるみたいだが、よく分からないがとりあえずヒープ最大を20GBくらいに増やす。
ros config set dynamic-space-size 20000
10万回は通ったのでこれで何度か実行する。
(time (dotimes (_ 100000) (run "INSERT INTO bench1 VALUES (?, ?, ?);" :params (list (print-object (uuid:make-v4-uuid) nil) (random 100) (random 100.0)) :silent t)))
10万回ループのデータ登録を10回実行する。 10万回あたりだいたい145秒かかった。
SxQLの導入
SQLを文字列で埋め込んでいくのも面倒なのでSxQLを導入する。
(ql:quickload :sxql) (defun run (sxql &key silent) (multiple-value-bind (sql binds) (sxql:yield sxql) (pprint sql) (let ((query (dbi:execute (dbi:prepare *connection* sql) binds))) (unless silent (loop for row = (dbi:fetch query) while row do (pprint row))))))
レコードの全数カウント。
(time (run (sxql:select ((:count :*)) (sxql:from :bench1))))