PostgreSQL/調査検証

パーティション性能

PostgreSQLでは、バージョン10から宣言的パーティションが使えるようになっている。
10以前はトリガを使用することで、別々のテーブルにアクセスする必要があった。

またPostgreSQL11から12に変わり、パーティション性能の向上が図られた。
ここでは、簡単なアプリケーションを使ってパーティション性能について測定した結果を参考までに記載する。

測定環境

個人用のデスクトップ環境で以下の通り。

項目スペック
OS macOS High Sierra10.13.6(17G9016)
ModeliMac (27-inch, Late 2012)
CPU3.2 GHz Intel Core i5
メモリ32 GB 1600 MHz DDR3
グラフィックスNVIDIA GeForce GTX 680MX 2048 MB

測定条件

  1. PostgreSQL 11.6 / 12.1
  2. パーティション / パーティション子テーブルアクセス / 非パーティション
  3. シングルプロセス / マルチプロセス

測定用資材

測定に使ったアプリケーション一式は、以下の通り。

アプリケーション

psycopg2のインストールが必要

$ pip install psycopg2

セットアップ&実行スクリプト

結果

1プロセス

partition-1proc.png

5プロセス

partition-5proc.png

PostgreSQL11と12でのパーティションのロック

PostgreSQL11

PostgreSQL11では、親テーブルのロックを得ると、データレンジにない子テーブルのロックも獲得される。

$ ./partition_test.sh --part 1000 20
$ psql -d postgres
psql (11.6)
TYPE "help" FOR help.

postgres=# \d+ part_*;
                                  TABLE "public.part_tbl"
 COLUMN |  TYPE   | Collation | NULLABLE | DEFAULT | Storage  | Stats target | Description 
--------+---------+-----------+----------+---------+----------+--------------+-------------
 id     | INTEGER |           |          |         | plain    |              | 
 msg    | text    |           |          |         | extended |              | 
Partition KEY: RANGE (id)
Partitions: part_tbl_1 FOR VALUES FROM (1) TO (1001),
            part_tbl_10 FOR VALUES FROM (9001) TO (10001),
            part_tbl_11 FOR VALUES FROM (10001) TO (11001),
            part_tbl_12 FOR VALUES FROM (11001) TO (12001),
            part_tbl_13 FOR VALUES FROM (12001) TO (13001),
            part_tbl_14 FOR VALUES FROM (13001) TO (14001),
            part_tbl_15 FOR VALUES FROM (14001) TO (15001),
            part_tbl_16 FOR VALUES FROM (15001) TO (16001),
            part_tbl_17 FOR VALUES FROM (16001) TO (17001),
            part_tbl_18 FOR VALUES FROM (17001) TO (18001),
            part_tbl_19 FOR VALUES FROM (18001) TO (19001),
            part_tbl_2 FOR VALUES FROM (1001) TO (2001),
            part_tbl_20 FOR VALUES FROM (19001) TO (20001),
            part_tbl_3 FOR VALUES FROM (2001) TO (3001),
            part_tbl_4 FOR VALUES FROM (3001) TO (4001),
            part_tbl_5 FOR VALUES FROM (4001) TO (5001),
            part_tbl_6 FOR VALUES FROM (5001) TO (6001),
            part_tbl_7 FOR VALUES FROM (6001) TO (7001),
            part_tbl_8 FOR VALUES FROM (7001) TO (8001),
            part_tbl_9 FOR VALUES FROM (8001) TO (9001)

                                 TABLE "public.part_tbl_1"
 COLUMN |  TYPE   | Collation | NULLABLE | DEFAULT | Storage  | Stats target | Description 
--------+---------+-----------+----------+---------+----------+--------------+-------------
 id     | INTEGER |           |          |         | plain    |              | 
 msg    | text    |           |          |         | extended |              | 
Partition OF: part_tbl FOR VALUES FROM (1) TO (1001)
Partition CONSTRAINT: ((id IS NOT NULL) AND (id >= 1) AND (id < 1001))

-- ページ節約のため、残りのテーブル情報については省略

postgres=# BEGIN;
BEGIN
postgres=# SELECT id FROM part_tbl WHERE id = 1;
 id 
----
  1
(1 ROW)

postgres=# UPDATE part_tbl SET msg = 'hoge' WHERE id = 1;
UPDATE 1
-- select実行後にpg_locksを参照
postgres=# SELECT pl.pid, pc.relname, pl.mode FROM pg_locks pl INNER JOIN pg_class pc ON (pl.relation = pc.oid) WHERE pl.pid = 83066;
  pid  |   relname   |      mode       
-------+-------------+-----------------
 83066 | part_tbl    | AccessShareLock
 83066 | part_tbl_17 | AccessShareLock
 83066 | part_tbl_5  | AccessShareLock
 83066 | part_tbl_18 | AccessShareLock
 83066 | part_tbl_9  | AccessShareLock
 83066 | part_tbl_13 | AccessShareLock
 83066 | part_tbl_15 | AccessShareLock
 83066 | part_tbl_16 | AccessShareLock
 83066 | part_tbl_20 | AccessShareLock
 83066 | part_tbl_1  | AccessShareLock
 83066 | part_tbl_10 | AccessShareLock
 83066 | part_tbl_2  | AccessShareLock
 83066 | part_tbl_6  | AccessShareLock
 83066 | part_tbl_3  | AccessShareLock
 83066 | part_tbl_7  | AccessShareLock
 83066 | part_tbl_11 | AccessShareLock
 83066 | part_tbl_14 | AccessShareLock
 83066 | part_tbl_4  | AccessShareLock
 83066 | part_tbl_8  | AccessShareLock
 83066 | part_tbl_12 | AccessShareLock
 83066 | part_tbl_19 | AccessShareLock
(21 ROWS)

-- update実行後に再度pg_locksを参照
postgres=# SELECT pl.pid, pc.relname, pl.mode FROM pg_locks pl INNER JOIN pg_class pc ON (pl.relation = pc.oid) WHERE pl.pid = 83066;
  pid  |   relname   |       mode       
-------+-------------+------------------
 83066 | part_tbl    | RowExclusiveLock
 83066 | part_tbl    | AccessShareLock
 83066 | part_tbl_17 | RowExclusiveLock
 83066 | part_tbl_17 | AccessShareLock
 83066 | part_tbl_5  | RowExclusiveLock
 83066 | part_tbl_5  | AccessShareLock
 83066 | part_tbl_18 | RowExclusiveLock
 83066 | part_tbl_18 | AccessShareLock
 83066 | part_tbl_9  | RowExclusiveLock
 83066 | part_tbl_9  | AccessShareLock
 83066 | part_tbl_13 | RowExclusiveLock
 83066 | part_tbl_13 | AccessShareLock
 83066 | part_tbl_15 | RowExclusiveLock
 83066 | part_tbl_15 | AccessShareLock
 83066 | part_tbl_16 | RowExclusiveLock
 83066 | part_tbl_16 | AccessShareLock
 83066 | part_tbl_20 | RowExclusiveLock
 83066 | part_tbl_20 | AccessShareLock
 83066 | part_tbl_1  | RowExclusiveLock
 83066 | part_tbl_1  | AccessShareLock
 83066 | part_tbl_10 | RowExclusiveLock
 83066 | part_tbl_10 | AccessShareLock
 83066 | part_tbl_2  | RowExclusiveLock
 83066 | part_tbl_2  | AccessShareLock
 83066 | part_tbl_6  | RowExclusiveLock
 83066 | part_tbl_6  | AccessShareLock
 83066 | part_tbl_3  | RowExclusiveLock
 83066 | part_tbl_3  | AccessShareLock
 83066 | part_tbl_7  | RowExclusiveLock
 83066 | part_tbl_7  | AccessShareLock
 83066 | part_tbl_11 | RowExclusiveLock
 83066 | part_tbl_11 | AccessShareLock
 83066 | part_tbl_14 | RowExclusiveLock
 83066 | part_tbl_14 | AccessShareLock
 83066 | part_tbl_4  | RowExclusiveLock
 83066 | part_tbl_4  | AccessShareLock
 83066 | part_tbl_8  | RowExclusiveLock
 83066 | part_tbl_8  | AccessShareLock
 83066 | part_tbl_12 | RowExclusiveLock
 83066 | part_tbl_12 | AccessShareLock
 83066 | part_tbl_19 | RowExclusiveLock
 83066 | part_tbl_19 | AccessShareLock
(42 ROWS)

PostgreSQL12

PostgreSQL12では、対象の子テーブルのみのロックが取られている。

$ psql -d postgres
psql (12.1)
TYPE "help" FOR help.

postgres=# BEGIN;
BEGIN
postgres=# SELECT id FROM part_tbl WHERE id = 1;
 id 
----
  1
(1 ROW)

postgres=# UPDATE part_tbl SET msg = 'hoge' WHERE id = 1;
UPDATE 1
postgres=# SELECT pl.pid, pc.relname, pl.mode FROM pg_locks pl INNER JOIN pg_class pc ON (pl.relation = pc.oid) WHERE pl.pid = 86768;
  pid  |  relname   |      mode       
-------+------------+-----------------
 86768 | part_tbl   | AccessShareLock
 86768 | part_tbl_1 | AccessShareLock
(2 ROWS)

postgres=# SELECT pl.pid, pc.relname, pl.mode FROM pg_locks pl INNER JOIN pg_class pc ON (pl.relation = pc.oid) WHERE pl.pid = 86768;
  pid  |  relname   |       mode       
-------+------------+------------------
 86768 | part_tbl   | RowExclusiveLock
 86768 | part_tbl   | AccessShareLock
 86768 | part_tbl_1 | RowExclusiveLock
 86768 | part_tbl_1 | AccessShareLock
(4 ROWS)

参考リンク


トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
目次
ダブルクリックで閉じるTOP | 閉じる
GO TO TOP