1. Conclusion
– Adding an index didn’t make it much faster.
2. Install PostgreSQL
– reference https://www.postgresql.org/download/linux/ubuntu/
$ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - sudo apt-get update sudo apt-get -y install postgresql [sudo] password for wsd01: ... Creating config file /etc/postgresql-common/createcluster.conf with new version Building PostgreSQL dictionaries from installed myspell/hunspell packages... en_us Removing obsolete dictionary files: Created symlink /etc/systemd/system/multi-user.target.wants/postgresql.service → /lib/systemd/system/postgresql.service. Setting up postgresql-14 (14.5-1.pgdg22.04+1) ... Creating new PostgreSQL cluster 14/main ... /usr/lib/postgresql/14/bin/initdb -D /var/lib/postgresql/14/main --auth-local peer --auth-host scram-sha-256 --no-instructions データベースシステム内のファイルの所有者はユーザー"postgres"となります。 このユーザーをサーバープロセスの所有者とする必要があります。 データベースクラスタはロケール"ja_JP.UTF-8"で初期化されます。 デフォルトのデータベース符号化方式はそれに対応してUTF8に設定されました。 initdb: ロケール"ja_JP.UTF-8"用の適切なテキスト検索設定が見つかりませんでした デフォルトのテキスト検索構成は simple に設定されます。 データベージのチェックサムは無効です。 ディレクトリ/var/lib/postgresql/14/mainの権限を設定しています ... ok サブディレクトリを作成しています ... ok 動的共有メモリの実装を選択しています ... posix デフォルトのmax_connectionsを選択しています ... 100 デフォルトのshared_buffersを選択しています ... 128MB デフォルトの時間帯を選択しています ... Asia/Tokyo 設定ファイルを作成しています ... ok ブートストラップスクリプトを実行しています ... ok ブートストラップ後の初期化を実行しています ... ok データをディスクに同期しています... ok update-alternatives: /usr/share/man/man1/postmaster.1.gz (postmaster.1.gz) を提供するために自動モードで /usr/share/postgresql/14/man/man1/postmaster.1.gz を使います Setting up postgresql (14+243.pgdg22.04+1) ... Processing triggers for man-db (2.10.2-1) ... Processing triggers for libc-bin (2.35-0ubuntu3.1) ... $
3. Confirm
$ sudo apt list --installed|grep postgresql WARNING: apt does not have a stable CLI interface. Use with caution in scripts. postgresql-14/jammy-pgdg,now 14.5-1.pgdg22.04+1 amd64 [installed,automatic] postgresql-client-14/jammy-pgdg,now 14.5-1.pgdg22.04+1 amd64 [installed,automatic] postgresql-client-common/jammy-pgdg,now 243.pgdg22.04+1 all [installed,automatic] postgresql-common/jammy-pgdg,now 243.pgdg22.04+1 all [installed,automatic] postgresql/jammy-pgdg,now 14+243.pgdg22.04+1 all [installed]
4. External connection permission
$ sudo vi /etc/postgresql/14/main/postgresql.conf #listen_addresses = 'localhost' listen_addresses = '*'
5. IPv4 local connections
$ sudo vi /etc/postgresql/14/main/pg_hba.conf # IPv4 local connections: host all all 127.0.0.1/32 scram-sha-256 host all all 192.168.1.1/24 scram-sha-256
6. Service restart
$ sudo service postgresql restart
6. Create user
$ sudo su - postgres $ pwd /var/lib/postgresql $ ls 14 $ createuser --pwprompt --interactive pgadmin 新しいロールのためのパスワード: [パスワード入力] もう一度入力してください: [上記とパスワード入力] 新しいロールをスーパユーザにしますか? (y/n)y
8. Connect from HeidiSQL
(1) Session manager
(2) After connection
9. Connect to postgres from terminal
$ psql -h localhost -U pgadmin -d postgres
ユーザー pgadmin のパスワード:
psql (14.5 (Ubuntu 14.5-1.pgdg22.04+1))
SSL 接続 (プロトコル: TLSv1.3、暗号化方式: TLS_AES_256_GCM_SHA384、ビット長: 256、圧縮: オフ)
“help”でヘルプを表示します。
10. Index effect measurement
– reference
https://symfoware.blog.fc2.com/blog-entry-2527.html
11. Create table
postgres=# CREATE TABLE json_test (doc json);
CREATE TABLE
postgres=# CREATE TABLE jsonb_test (doc jsonb);
CREATE TABLE
postgres=#
12. Check with HeidiSQL
13. exit psql
postgres=# \q $
14. python version
$ python3 -V Python 3.10.6
15. exit postgres
exit $
16. install python3-psycopg2
$ sudo apt-get -y install python3-psycopg2
17. confirm python3-psycopg2
$ sudo apt list --installed|grep python3-psycopg2 WARNING: apt does not have a stable CLI interface. Use with caution in scripts. python3-psycopg2/jammy-pgdg,now 2.9.4-1.pgdg22.04+1 amd64 [installed] $
18. Data registration program(python)
– table : json_test
$ sudo su - postgres $ cat insert.py import psycopg2 import psycopg2.extras con = psycopg2.connect( host = 'localhost', port = 5432, database='postgres', user='pgadmin', password='123456') cur = con.cursor() for i in range(1, 1000001): cur.execute("INSERT INTO json_test(doc) VALUES (%s)", [psycopg2.extras.Json({'id': i, 'value':'value1-%d' % (i)})]) if i % 10000 == 0: print(i) con.commit() con.commit() cur.close() con.close()
19. Data registration execution
$ python3 insert.py 10000 20000 ... 990000 1000000 $
20. Check with HeidiSQL
21. Data registration program(python)
– table : jsonb_test
$ sudo su - postgres $ cat insert.py import psycopg2 import psycopg2.extras con = psycopg2.connect( host = 'localhost', port = 5432, database='postgres', user='pgadmin', password='123456') cur = con.cursor() for i in range(1, 1000001): cur.execute("INSERT INTO jsonb_test(doc) VALUES (%s)", [psycopg2.extras.Json({'id': i, 'value':'value1-%d' % (i)})]) if i % 10000 == 0: print(i) con.commit() con.commit() cur.close() con.close()
22. Data registration execution
$ python3 insert.py 10000 20000 ... 990000 1000000 $
23. Check with HeidiSQL
24. select.py
– table : json_test
$ cat select.py import psycopg2 import time import psycopg2.extras con = psycopg2.connect( host = 'localhost', port = 5432, database='postgres', user='pgadmin', password='123456') cur = con.cursor() start_time = time.perf_counter() cur.execute("SELECT * FROM json_test where doc->>'id' = '1';") con.commit() execution_time = time.perf_counter() - start_time print(execution_time) cur.close() con.close()
25. Run time of select.py
$ python3 select.py 0.2227892939990852 $
26. select2.py
– table : jsonb_test
$ cat select.py import psycopg2 import time import psycopg2.extras con = psycopg2.connect( host = 'localhost', port = 5432, database='postgres', user='pgadmin', password='123456') cur = con.cursor() start_time = time.perf_counter() cur.execute("SELECT * FROM jsonb_test where doc->>'id' = '1';") con.commit() execution_time = time.perf_counter() - start_time print(execution_time) cur.close() con.close()
27. Run time of select2.py
$ python3 select2.py 0.11176194200379541 $
28. @>演算子
$ psql -h localhost -U pgadmin -d postgres ユーザー pgadmin のパスワード: psql (14.5 (Ubuntu 14.5-1.pgdg22.04+1)) SSL 接続 (プロトコル: TLSv1.3、暗号化方式: TLS_AES_256_GCM_SHA384、ビット長: 256、圧縮: オフ) "help"でヘルプを表示します。 postgres=# SELECT * FROM jsonb_test where doc @> '{"id":1}'; doc -------------------------------- {"id": 1, "value": "value1-1"} (1 行) postgres=# SELECT * FROM json_test where doc @> '{"id":1}'; ERROR: 演算子が存在しません: json @> unknown 行 1: SELECT * FROM json_test where doc @> '{"id":1}'; ^ HINT: 指定した名称と引数の型に合う演算子がありません。明示的な型キャストが必要かもしれません。 postgres=# SELECT * FROM json_test where doc::jsonb @> '{"id":1}'; doc -------------------------------- {"id": 1, "value": "value1-1"} (1 行) postgres=#
29. Query plan
postgres=# EXPLAIN SELECT * FROM json_test where doc::jsonb @> '{"id":1}'; QUERY PLAN -------------------------------------------------------------------------------- Gather (cost=1000.00..18536.67 rows=10000 width=40) Workers Planned: 2 -> Parallel Seq Scan on json_test (cost=0.00..16536.67 rows=4167 width=40) Filter: ((doc)::jsonb @> '{"id": 1}'::jsonb) (4 行) postgres=# EXPLAIN SELECT * FROM jsonb_test where doc @> '{"id":1}'; QUERY PLAN ------------------------------------------------------------------------------- Gather (cost=1000.00..16518.33 rows=100 width=51) Workers Planned: 2 -> Parallel Seq Scan on jsonb_test (cost=0.00..15508.33 rows=42 width=51) Filter: (doc @> '{"id": 1}'::jsonb) (4 行) postgres=#
30. Create index
postgres=# CREATE INDEX idx_doc ON jsonb_test USING GIN (doc); CREATE INDEX postgres=#
31. Check with HeidiSQL
32. exec select2.py add index
$ python3 select2.py 0.10611801099730656
33. exec select2.py add index without commit
$ python3 select2.py 0.10100354099995457
34. Query plan (josonb_test)
postgres=# EXPLAIN SELECT * FROM jsonb_test where doc @> '{"id":1}'; QUERY PLAN ------------------------------------------------------------------------- Bitmap Heap Scan on jsonb_test (cost=36.77..408.47 rows=100 width=51) Recheck Cond: (doc @> '{"id": 1}'::jsonb) -> Bitmap Index Scan on idx_doc (cost=0.00..36.75 rows=100 width=0) Index Cond: (doc @> '{"id": 1}'::jsonb) (4 行) postgres=#
35. Query plan (json_test)
postgres=# EXPLAIN SELECT * FROM jsonb_test where doc->'id' = '1'; Gather (cost=1000.00..18050.00 rows=5000 width=51) Workers Planned: 2 -> Parallel Seq Scan on jsonb_test (cost=0.00..16550.00 rows=2083 width=51) Filter: ((doc -> 'id'::text) = '1'::jsonb) (4 行)
36. result ( python3 select2.py )
– no index : 0.11176194200379541 (#27)
– add index: 0.10611801099730656 (#32)