Sqlite学習ノート(二)&&性能テスト

7499 ワード

テストターゲット
SQliteの一般的なパフォーマンス指標の取得
テスト環境
CPU:8コア、Intel(R)Xeon(R)CPU E [email protected] GHz
メモリ:16 G
ディスク:SSD
Linux 2.6.32
SQlite最新バージョン3.8.11
シーンのテスト
1)主キークエリーテスト
2)主キー更新テスト
3)一括導入テスト
初期化
1)テストテーブル構造
CREATE TABLE user( id integer primary key autoincrement, c1 int, c2 varchar(1000), c3 varchar(1000));
CREATE TABLE orders( id integer primary key autoincrement, user_id int, c1 varchar(1000), c2 varchar(1000));

2)イニシャルデータ
プログラムによりuserテーブルとordersテーブルに10 wレコードをインポートし,dbファイル全体が400 M程度である.
3)試験説明
sqlite自体はPRAGMAコマンドでプログラムキャッシュサイズ(cache_size)を設定できますが、sqliteのキャッシュポリシーではオペレーティングシステムキャッシュの影響は無視されていませんので、本稿のテスト結果ではデフォルトのcache_を使用します.size(2000 page)は,数回のテストで平均値をとることで,おおよその性能指標を得た.さらに、sqliteは主に組み込み機器に用いられるが、本明細書のテストはPCに基づいているため、テストデータは参照にすぎない.
単一テーブル・プライマリ・キー・クエリー
1)試験説明
このテストでは、プライマリ・キー・クエリーのパフォーマンスを主にテストし、次のような文の形をテストします.
「select*from user where id=xxx」では、xxxはランダム関数で生成されます.生成されたテストデータidの範囲は[1-10000]であるため、ランダム関数で[1-100000]のランダム数を生成し、1%のヒット率を基本的に保証できます(実際のテストで証明されています).Sqliteはリードコンカレントをサポートするため、このテストはマルチスレッドコンカレントの場合の性能をテストし、テスト結果の時間単位はミリ秒(ms)である.マルチスレッドテストモデルは簡単で、各スレッドは同じクエリーを10 w回実行し、総消費時間を計算し、平均値と時間の比に基づいてQPSとTPSを計算し、パラメータSQLITE_を通過する.OPEN_SHAREDCACHEは、共有キャッシュモードを有効にするかどうかを制御します. 
2)テスト結果
a)非共有キャッシュモード
 
スレッド数
1
2
4
8
16
第1ラウンド
2886
3641
8392
19615
27875
第2ラウンド
2867
3933
8088
21010
28635
第3ラウンド
2821
4131
8077
21220
28689
第4ラウンド
2941
4011
7787
20983
27965
第5ラウンド
2896
3724
7881
21332
28654
へいきんち
2881
3949
7958
21136
28363
CPU%
80%
180%
320%
670%
710%
QPS
3.4w
5w
5w
3.8w
5.6w
表1
b)共有キャッシュモード
スレッド数
1
2
4
第1ラウンド
3050
12616
26554
第2ラウンド
3077
12331
26396
第3ラウンド
3131
12327
27070
第4ラウンド
3096
13014
27031
第5ラウンド
2972
12866
27778
へいきんち
3065
12634
26965
CPU%
80%
120%
120%
QPS
3.3w
1.5w
1.4w
表2
3)結果分析
表1の結果から、同時性が向上するにつれて、ホストCPUの利用率も上昇する.QPSは単一スレッド3.4 wから4スレッドに上昇して5 w程度を併発したが、8スレッドになるとまた一定の下落が現れ、16スレッドが併発するとQPSはまた5 w程度に戻った.テスト中、CPU利用率とディスクIOを観察することにより、基本的にCPUがQPSの上昇を制限していると断定できる.ホストCPUコア数は8コアであるため、CPUの利用率は高く、800%近くまで可能であり、ほぼ限界に達している.もちろん、絶対値から見ると毎秒5 wのクエリー性能も、確かにいいです!
表2の結果から,共有キャッシュモードを設定すると,同時性能が大きく低下し,CPU利用率から一斑が見られ,QPSは単一スレッド3.3 wから8スレッド1.4 w程度に低下した.この点については、なぜ共有キャッシュを開いたのか、同時パフォーマンスが低下したのか疑問に思っています.プログラムの実行中にスタックをキャプチャし、ソースコードと組み合わせて理由を見つけることで、同時にクエリを行うと、sqlite 3 BtreeEnter関数のmutexに大量のスレッドが詰まってしまいます.共有メモリモードでは、プロセス内の複数のスレッドが同じBツリーオブジェクトを共有することで、共有メモリの目的を達成し、Bツリーオブジェクトが1つのmutexで保護されるのは、このmutexの競争によって、同時性が著しく低下するためです.したがって、共有メモリモードはメモリの使用を減らすことができますが、同時パフォーマンスを犠牲にします.
上記のテストは、実際にはマルチスレッドモードでの共有および非共有モードでのテスト結果です.実際にsqlite接続を使用するには、単一スレッドモード、マルチスレッドシリアル化モード、マルチスレッドモードのいくつかの方法があります.一般的には、フェーズ指定をコンパイルしたり、データベース接続を開いたりするときに指定したり、実行時に指定したりすることができます.(1)コンパイル段階のいくつかのモードはパラメータSQLITE_を通過することができるTHREADAFEはコンパイル段階で指定され、0,1,2の値をとることができ、デフォルトは1である.この3つの値の意味は、0:単一スレッドモード、すなわち内部がmutex保護されず、マルチスレッドがsqliteを実行するのは安全ではない.1:マルチスレッドのシリアルモード、sqliteはマルチスレッドのシリアル化を支援します.2:マルチスレッドの同時モードで、同じ時刻に同じ接続が複数のスレッドで使用されないことを要求します.(2)データベースを開く段階では、コンパイル段階で実行モードを指定するほか、データベースを開くとき(sqlite 3_open_v 2())にパラメータで指定することもできます.主なパラメータと意味は以下の通りです.SQLITE_OPEN_NOMUTEX:データベース接続をマルチスレッドモード(シングルスレッドモードが指定されていない場合)で実行するSQLITE_を設定するOPEN_FULLMUTEX:データベース接続をシリアルモードで実行するように設定します.SQLITE_OPEN_SHAREDCACHE:共有キャッシュモードで実行するように設定します.SQLITE_OPEN_PRIVATECACHE:非共有キャッシュモードで実行するように設定します.SQLITE_OPEN_READWRITE:データベース接続が読み書き可能であることを指定します.SQLITE_OPEN_CREATE:データベースが存在しない場合に作成します.(3)ランタイムフェーズでsqlite 3_を呼び出すconfigインタフェースは、運転モードを設定することもできます.パラメータSQLITE_をコンパイルする場合THREADSAFE=1 or SQLITE_THREADSCAFE=2であれば、実行時にスレッドモードを設定することができる.SQLITE_CONFIG_SINGLETHREAD:シングルスレッドモードSQLITE_CONFIG_MULTITHREAD:マルチスレッドモード、アプリケーション層は同じ時刻を保証し、同じ接続は1つのスレッドしか使用しません.SQLITE_CONFIG_SERIALIZED:シリアルモード、sqliteはマルチスレッドのシリアル化を支援します.
一括ロードテスト
1)試験説明
データのインポートはdbで最も一般的な機能です.このテストでは、主に3つのモードのインポート性能、単行単一トランザクション、マルチロートランザクション、prepareモードのマルチロートランザクションをテストします.主なモデルは次のとおりです.
a)一方通行取引
begin
insert into user values(1,’xxx’); commit; begin
insert into user values(1,’xxx’); commit; ……

b)マルチラインシングル取引
begin
insert into user values(1,’xxx’);insert into user values(2,’xxx’);…… commit;

c)prepareバインド
begin
prepare insert into user(id, c1) values(?,?); bind (id,c1) …… commit;

2)テスト結果
 
1行トランザクション
10 w行トランザクション
10 w行トランザクション(prepare)
第1ラウンド
1693533
11856
9079
第2ラウンド
1673983
11667
8375
第3ラウンド

12075
8566
第4ラウンド

11611
8773
第5ラウンド

11331
8660
へいきんち
 
11671
8593
TPS
60
8568
1.16w
表3
3)結果分析
テスト結果から、1行トランザクションと複数行トランザクションの差が非常に大きいことは、dbにとってトランザクションコミット動作が非常に時間がかかることを十分に示しています.一方、10 w行のトランザクションTPSは8500に達し、100倍以上向上した.従来のDBMSと同様に、sqliteがトランザクションをコミットする場合も、遅いブラシ動作を行う必要があるため、1回のブラシと10 wのブラシでは性能の差が非常に大きい.3番目の欄はprepareタイプのトランザクションであり、10 w行をトランザクション単位として採用していますが、より効果的です.これはprepareモデルトランザクションを採用しているため,10 w行の記録は1回しか解析できないが,前者は10 w回解析する必要があり,解析時間は長くないが蓄積が少ないため,第3欄ではこの最適化点だけでTPSを8500から1.16 wに昇格させる.
プライマリ・キーの更新
1)試験説明
このテスト例の文も非常に簡単です.簡単なプライマリ・キーの更新で、カラム値を1から増やします.テスト文形は、update user set c 1=c 1+1 where id=xxxのようです.SQLiteは同時更新をサポートしていないため、テスト書き込みはすべて単一スレッドです.単一ロー・トランザクション、複数ロー・トランザクションをそれぞれシミュレートし、SQLiteの更新パフォーマンスを観察します.1 w行の更新、プログラムの実行時間を統計し、更新記録数と実行時間からTPSを計算する.
2)テスト結果
 
1行トランザクション
1000行のトランザクション
1 wロートランザクション
第1ラウンド
164784
16623
16232
第2ラウンド
170256
16382
17514
第3ラウンド
166387
17099
17696
第4ラウンド
172987
17030
17753
第5ラウンド
166543
16386
17787
へいきんち
169043
16724
17832
TPS
59
598
560.7
表4
3)結果分析
マルチロートランザクションについては、基本的にインポート操作と同様に、マルチロートランザクションのパフォーマンスが大幅に向上します.また,更新されたTPSは挿入されたTPSに比べてかなり異なることも見られる.個人的にこの現象はディスクIOと大きな関係があると推定されている.挿入時、プライマリキーが自増したため、書くのは順番に書くからだ.本測定例の更新はランダムに更新され,生成された汚れたページはcacheよりはるかに大きい.sizeは、大量のランダム書き込みを伴うに違いなく、更新性能が悪い.