20150530 pgunconf-pgbench-semi-structured-benchmark
TRANSCRIPT
PostgreSQL Unconference(2015-05-30)
XML, hsotre, JSON, JSONB pgbench Benchmark
ぬこ@横浜 (@nuko_yokohama)
XML 型
XML を格納するデータ型属性、階層、順序、名前空間対応
本体機能 (configure で指定 )格納時に XML パースを行なう型自体に比較演算機能はないxpath によるアクセスが可能libxml2 ライブラリに依存
XML 型の処理XML 文字列
XML パーサ
XML 型(文字列)
XML 文字列
関数の結果
(そのまま出力)
格納時
取り出し時
xpath関数
XML パーサ関数処理
xpath 処理
パーサではチェックのみを行う
PostgreSQLストレージ
hstore 型の処理 ( たぶん )hstore 文字列
hstore パーサ
hstore 型(バイナリ)
hstore 文字列
関数の結果
文字列化
格納時
取り出し時
hstore関数
関数処理 バイナリを直接解釈して関数実行
パーサは動作しない
PostgreSQLストレージシリアライズ
JSON 型の処理JSON 文字列
JSON ツリーJSON パーサ
JSON 型(文字列)
JSON 文字列
関数の結果
(そのまま出力)
格納時
取り出し時
JSON関数
JSON パーサ関数処理
JSON ツリー
パーサで生成したJSONツリーは捨てられる
PostgreSQLストレージ
JSONB 型の処理JSON 文字列
JSON ツリーJSON パーサ
JSONB 型(バイナリ)
JSON 文字列
関数の結果
文字列化
格納時
取り出し時
JSONB関数
関数処理 バイナリを直接解釈して関数実行
パーサは動作しない
PostgreSQLストレージシリアライズ
XML, hstore, JSON 比較データ型 表現能力 格納領域 処理性能XML ◎ △ △hstore △ ○ ◎JSON ○ ○ ○JSONB ○ ○ ◎
XML は表現能力は高いが扱いにくいhstore はシンプルだが速いJSONB は良いとこ取り?⇒ 用途で使い分け可能
本当か?
pgbench モデルのテーブル
bench=# \d pgbench_accounts; Table "public.pgbench_accounts" Column | Type | Modifiers ----------+---------------+----------- aid | integer | not null bid | integer | abalance | integer | filler | character(84) | Indexes: "pgbench_accounts_pkey" PRIMARY KEY, btree (aid)
通常の pgbench モデル
XML モデルbench_xml=# \d accounts Table "public.accounts" Column | Type | Modifiers --------+------+----------- data | xml | Indexes: "xml_aid_idx" btree (((xpath('/accounts/aid/text()'::text, data)::text[])[1]::integer))
pgbench モデルのテーブルbench_hstore=# \d accounts Table "public.accounts" Column | Type | Modifiers --------+--------+----------- data | hstore | Indexes: "hstore_aid_idx" btree (((data -> 'aid'::text)::integer))
hstore モデル
JSONB モデル
bench_json=# \d accounts Table "public.accounts" Column | Type | Modifiers --------+------+----------- data | json | Indexes: "json_aid_idx" btree (((data ->> 'aid'::text)::integer))
JSON モデル
( JSON モデルとだいたいおなじ)今回は GIN インデックスパターンは
使いません
pgbench モデルのクエリ
BEGIN;UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;SELECT abalance FROM pgbench_accounts WHERE aid = :aid;UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);END;
通常の pgbench モデル(抜粋)
pgbench モデルのクエリ
UPDATE accounts SET data = xmlelement(name accounts, null, xmlelement(name aid, null, ((xpath('/accounts/aid/text()', data))::text[])[1]), xmlelement(name bid, null, ((xpath('/accounts/bid/text()', data))::text[])[1]), xmlelement(name abalance, null, (((xpath('/accounts/abalance/text()', data))::text[])[1])::int + :delta ), xmlelement(name filler, null, ((xpath('/accounts/filler/text()', data))::text[])[1])) WHERE (xpath('/accounts/aid/text()', data)::text[])[1]::int = :aid;
SELECT ((xpath('/accounts/abalance/text()', data))::text[])[1]::int FROM accounts WHERE ((xpath('/accounts/aid/text()', data))::text[])[1]::int = :aid;
INSERT INTO history (data) VALUES ( xmlelement(name history, null, xmlelement(name tid, null, :tid), xmlelement(name bid, null, :bid), xmlelement(name aid, null, :aid), xmlelement(name delta, null, :delta), xmlelement(name mtime, null, CURRENT_TIMESTAMP), xmlelement(name filler, null, ' ')));
XML の pgbench モデル(抜粋)
pgbench モデルのクエリ
UPDATE accounts SET data = data || hstore('abalance', ((data->'abalance')::int + :delta)::text ) WHERE (data->'aid')::int = :aid;
SELECT data->'abalance' FROM accounts WHERE (data->'aid')::int = :aid;
INSERT INTO history (data) VALUES ( hstore( ARRAY['tid','bid','aid','delta','mtime', 'filler'], ARRAY[ ( :tid )::text, ( :bid )::text, ( :aid )::text, ( :delta )::text, CURRENT_TIMESTAMP::text, ' ']));
hstore の pgbench モデル(抜粋)
pgbench モデルのクエリUPDATE accounts SET data = json_build_object( 'aid', (data->>'aid')::int, 'bid', (data->>'bid')::int, 'abalance', (data->>'abalance')::int + :delta , 'filler', data->>'filler') WHERE (data->>'aid')::int = :aid;
SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid;
INSERT INTO history (data) VALUES ( json_build_object( 'tid', :tid, 'bid', :bid, 'aid', :aid, 'delta', :delta, 'mtime', CURRENT_TIMESTAMP, 'filler', ' '));
JSON の pgbench モデル(抜粋)
pgbench モデルのクエリUPDATE accounts SET data = json_build_object( 'aid', (data->>'aid')::int, 'bid', (data->>'bid')::int, 'abalance', (data->>'abalance')::int + :delta , 'filler', data->>'filler')::jsonb WHERE (data->>'aid')::int = :aid;
SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid;
INSERT INTO history (data) VALUES ( json_build_object('tid', :tid, 'bid', :bid, 'aid', :aid, 'delta', :delta, 'mtime', CURRENT_TIMESTAMP, 'filler', ' ')::jsonb);
JSONB の pgbench モデル(抜粋)
pgbench モデルのクエリ
UPDATE accounts SET data = data || jsonb_build_object('abalance', (data->>'abalance')::int + :delta) WHERE (data->>'aid')::int = :aid;
SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid;
INSERT INTO history (data) VALUES ( jsonb_build_object( 'tid', :tid, ' bid', :bid, 'aid', :aid, 'delta', :delta, 'mtime', CURRENT_TIMESTAMP, 'filler', ' '));
JSONB(9.5) の pgbench モデル(抜粋)
PostgreSQL 9.5 では hstore 型と似たような部分更新の演算子 ( || ) が追加された!(あと jsonb_build_object が追加されたっぽい)
測定環境とモデルLet's note SX4
VMWare + CentOS 7.0PostgreSQL 9.5-devel
Scale Factor = 10( accounts:100 万件)
ホントはAWS EC2のいい感じのインスタンスを使いたかっけど間に合わなかった
XML おせえ(インデックス作成も)JSON チョットハヤイ
XML
hstore
JSON
JSONB
0.000 5000.000 10000.000 15000.000 20000.000 25000.000 30000.000
ロード時間およびインデックス作成時間
インデックス作成時間 (ms)
ロード時間 (ms)
このモデルだとカラム数が少ないからJSONB はやや冗長になるのかな
XML
hstore
JSON
JSONB
0 50000000 100000000 150000000 200000000 250000000
テーブルサイズ /インデックスサイズ
インデックスサイズ
テーブルサイズ
XML テラおせえhstore ギガ速い
JSONB-9.5 部分更新の効果も見える
XML
hstore
JSON
JSONB
JSONB-9.5
0 10000 20000 30000 40000 50000 60000 70000 80000
76042
5292
12508
12241
8829
100万件更新時間 (ms)
XML おせえ・ hstore 速いJSONB 9.5 部分更新の効果は低い?
XML
hstore
JSON
JSONB
JSONB-9.5
通常レコード
0 200 400 600 800 1000 1200 1400 1600 1800 2000
467.436
1360.219
1066.437
1149.694
1103.781
1708.898
pgbenchスループット (tps)
XML おせえ・ hstore 速いSELECT はあんまり差がないね
UPDATE accounts
SELECT accounts
UPDATE tellers
UPDATE branches
INSERT history
END
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
pgbenchレイテンシ (ms)
XML
hstore
JSON
JSONB
JSONB-9.5通常レコード
XML, hstore, JSON 比較データ型 表現能力 格納領域 処理性能XML ◎ △ △hstore △ ○ ◎JSON ○ ○ ○JSONB ○ ○ ◎
だいたいあってた!よかった!
ちょい微妙?