PostgreSQL 9.5 ハッシュ性能向上
10月にPostgreSQL 9.5 betaもリリースされるっぽいですね。
今日は9.5の小ネタ?であるハッシュ性能向上効果を見てみた。
試してみた
手元の環境(Let's note SX4/VMWare Player/CentOS 7)上で、以下の様な2種類のテーブルを用意して、
hash=# \d test_a Table "public.test_a" Column | Type | Modifiers --------+---------+----------- id | integer | not null data1 | integer | data2 | text | Indexes: "test_a_pkey" PRIMARY KEY, btree (id) hash=# \d test_b Table "public.test_b" Column | Type | Modifiers --------+---------+----------- id | integer | not null data1 | integer | data2 | integer | data3 | text | Indexes: "test_b_pkey" PRIMARY KEY, btree (id) hash=#
こんな感じでテキトーに100万件ほどデータを突っ込んでおく。
INSERT INTO test_a VALUES (generate_series(1,1000000), random() * 1000000, md5(clock_timestamp()::text)); INSERT INTO test_b VALUES (generate_series(1,1000000), random() * 1000000, random() * 2000000, md5(clock_timestamp()::text));
こういう環境をPostgreSQL 9.4.4/9.5alpha2上に構築しておく。
そして、各バージョン毎にHash Joinによる検索を実行して、そのEXPLAIN ANALYZE結果を比較してみた。
9.4.4のEXPLAIN ANALYZE結果
[nuko@localhost 9.5-hash]$ postgres --version postgres (PostgreSQL) 9.4.4 [nuko@localhost 9.5-hash]$ psql hash -e -f explain.sql EXPLAIN ANALYZE SELECT test_a.id, test_a.data2 FROM test_a INNER JOIN test_b ON test_a.data1 = test_b.data1 WHERE test_b.id < 1000; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- Hash Join (cost=40636.43..49770.10 rows=2124 width=37) (actual time=519.315..636.401 rows=943 loops=1) Hash Cond: (test_b.data1 = test_a.data1) -> Index Scan using test_b_pkey on test_b (cost=0.42..45.43 rows=1086 width=4) (actual time=0.009..0.234 rows=999 loops=1) Index Cond: (id < 1000) -> Hash (cost=19346.00..19346.00 rows=1000000 width=41) (actual time=518.490..518.490 rows=1000000 loops=1) Buckets: 8192 Batches: 32 Memory Usage: 2351kB -> Seq Scan on test_a (cost=0.00..19346.00 rows=1000000 width=41) (actual time=0.084..165.928 rows=1000000 loops=1) Planning time: 0.678 ms Execution time: 636.510 ms (9 rows)
9.5alpha2のEXPLAIN ANALYZE結果
[nuko@localhost 9.5-hash]$ postgres --version postgres (PostgreSQL) 9.5alpha2 [nuko@localhost 9.5-hash]$ psql hash -e -f explain.sql EXPLAIN ANALYZE SELECT test_a.id, test_a.data2 FROM test_a INNER JOIN test_b ON test_a.data1 = test_b.data1 WHERE test_b.id < 1000; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- Hash Join (cost=40636.43..49625.06 rows=1962 width=37) (actual time=357.597..447.943 rows=943 loops=1) Hash Cond: (test_b.data1 = test_a.data1) -> Index Scan using test_b_pkey on test_b (cost=0.42..43.05 rows=1007 width=4) (actual time=0.008..0.237 rows=999 loops=1) Index Cond: (id < 1000) -> Hash (cost=19346.00..19346.00 rows=1000000 width=41) (actual time=356.412..356.412 rows=1000000 loops=1) Buckets: 65536 Batches: 32 Memory Usage: 2826kB -> Seq Scan on test_a (cost=0.00..19346.00 rows=1000000 width=41) (actual time=0.027..150.604 rows=1000000 loops=1) Planning time: 0.612 ms Execution time: 448.060 ms (9 rows)
Hash性能の比較
で、上記のEXPLAIN ANALYZE結果から、Hashの部分とHash演算の元となるSeqScanのactual timeを見てみる。。
Hashのactual timeとSeq Scanのactual timeの差分、これがハッシュ処理そのものの時間だと考えられる。
で、そのハッシュ処理(100万件分のハッシュ処理)そのものの時間を9.4.4と9.5alpha2と比較するとこんな感じに。
絶対値でみるとそれほどの時間ではないものの、9.4,4と9.5alphaで比較してみると、比率的にはかなりハッシュ処理の時間が向上していると思われる。
こういう小さな性能向上の積み重ねが、PostgreSQL全体の性能向上に繋がっているんだよなーと改めて思う。