【PostgreSQL 11 新機能】HASH パーティショニングを検証してみた

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【5/21開催】Azure OpenAI ServiceによるRAG実装ガイドを公開しました
生成AIを活用したユースケースで最も一番熱いと言われているRAGの実装ガイドを公開しました。そのガイドの紹介をおこなうイベントです!!
https://tech-lab.connpass.com/event/315703/

こんにちは。サイオステクノロジー OSS サポート担当 Y です。

今回は PostgreSQL 11 (現時点ではまだ beta 版) の新機能である “HASH パーティショニング” を検証してみました。(※以下の内容は CentOS 7.5/PostgreSQL 11beta3 にて検証しています。)

■はじめに

昨年リリースされた PostgreSQL 10 の新機能である Declarative Partitioning では、RANGE パーティションと LIST パーティションの 2つの種類のパーティションを作成することができるのですが、PostgreSQL 11 ではこれらに加えて “HASH パーティション” が実装される予定となっています。

今回は PostgreSQL 11beta3 を使って、この HASH パーティションを試してみようと思います。

■検証

さて、まずはテーブルを作成してみます。親テーブル “hash_test” に対して子テーブル “hash_child_1”, “hash_child_2”, “hash_child_3” を作成しています。

postgres=# CREATE TABLE hash_test (data text) PARTITION BY HASH (data);
CREATE TABLE
postgres=# 
postgres=# CREATE TABLE hash_child_1 PARTITION OF hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 0);
CREATE TABLE
postgres=# 
postgres=# CREATE TABLE hash_child_2 PARTITION OF hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 1);
CREATE TABLE
postgres=# 
postgres=# CREATE TABLE hash_child_3 PARTITION OF hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 2);
CREATE TABLE
postgres=# 
postgres=# \d+ hash_test
                                Table "public.hash_test"
 Column | Type | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+------+-----------+----------+---------+----------+--------------+-------------
 data   | text |           |          |         | extended |              | 
Partition key: HASH (data)
Partitions: hash_child_1 FOR VALUES WITH (modulus 3, remainder 0),
            hash_child_2 FOR VALUES WITH (modulus 3, remainder 1),
            hash_child_3 FOR VALUES WITH (modulus 3, remainder 2)

上記の通り、HASH パーティションの場合も RANGE/LIST パーティションと同様に CREATE TABLE 文だけでパーティショニングされたテーブルを作成することが可能です。

FOR VALUES 句に指定している値の詳細については、まだ正確に把握できていないのですが、以下のドキュメントによると “modulus は正の整数”, “remainder は modulus より小さい負ではない整数” 等の複数の条件があるようです。

それでは、作成したテーブルにデータを INSERT してみます。今回は以下の様なランダムな文字列を生成して INSERT してみました。

postgres=# INSERT INTO hash_test SELECT md5(clock_timestamp()::text) as test_data FROM generate_series(1,6);
INSERT 0 6
postgres=# 
postgres=# SELECT * FROM hash_test;
               data               
----------------------------------
 7b889830662255538e88baff30130545
 336d0b62f2020f380a4f08aa56c37b97
 40d27ceb4af48dc8cb6324ac287cf71f
 813de88f6844a517a7f617c75ac8583f
 b5d30b6de905a42faf636b68c30d13ce
 5bf0458863cf2f10566634b7addbbf7d
(6 rows)

親テーブルにデータが INSERT されたことが確認できたので、次に各子テーブルのデータを確認してみます。

postgres=# SELECT * FROM hash_child_1;
               data               
----------------------------------
 7b889830662255538e88baff30130545
 336d0b62f2020f380a4f08aa56c37b97
 40d27ceb4af48dc8cb6324ac287cf71f
(3 rows)

postgres=# 
postgres=# SELECT * FROM hash_child_2;
               data               
----------------------------------
 813de88f6844a517a7f617c75ac8583f
(1 row)

postgres=# 
postgres=# SELECT * FROM hash_child_3;
               data               
----------------------------------
 b5d30b6de905a42faf636b68c30d13ce
 5bf0458863cf2f10566634b7addbbf7d
(2 rows)

上記の通り、先ほど親テーブルに INSERT したデータが子テーブルに分散されていることが確認できました。

また、一般的な HASH パーティショニングのメリットとして “データを均等に分散することができる” というものがあります。

上記の例では、レコード数が少ないため均等に分散されているようには見えませんが、レコード数が増えればある程度均等に分散されるはずです。

ということで、実際に 300万レコードほどデータを INSERT して、データが均等に分散されるかを確認してみます。

postgres=# INSERT INTO hash_test SELECT md5(clock_timestamp()::text) as test_data FROM generate_series(1,3000000);
INSERT 0 3000000
postgres=# 
postgres=# SELECT count(*) FROM hash_test;
  count  
---------
 3000000
(1 row)

postgres=# 
postgres=# SELECT count(*) FROM hash_child_1;
  count  
---------
 1000535
(1 row)

postgres=# 
postgres=# SELECT count(*) FROM hash_child_2;
  count  
---------
 1000318
(1 row)

postgres=# 
postgres=# SELECT count(*) FROM hash_child_3;
 count  
--------
 999147
(1 row)

すると、各子テーブルにほぼほぼ均等に (約 100万レコードずつ) データが分散されていることが確認できました。

■最後に

今回は PostgreSQL 11 で実装予定の “HASH パーティショニング” を試してみました。

検証内容に記載してある通り、HASH パーティショニングはデータを均等に分散してくれるので、複数の異なるディスク上に作成したテーブルスペースと組み合わせると、I/O 負荷を均等に分散することができるので、大規模なテーブルに HASH パーティショニングを適用すると、当該テーブルにアクセスする際の性能向上等が期待できるかもしれません。

アバター画像
About サイオステクノロジーの中の人 41 Articles
サイオステクノロジーで働く中の人です。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる