Technical Knowledge
目次
PostgreSQL
[アプリケーション]
listen_addresses の設定。
- 受信するインターフェースのサーバのアドレスを指定する。
192.168.1.* などの指定は出来ない。
listen_addresses = '192.168.1.*' # これは無効
全て許可する場合は * のみとする。
listen_addresses = '*'
複数のインターフェースの IP を指定可。
listen_addresses = 'localhost,192.1681.1,172.16.1.1'
テーブルの一覧取得等の SQL を調べる。
psql を -E オプション付きで起動して \d 等を行う。
# psql -E > \d
処理に時間がかかっている SQL を調べる。
postgresql.conf の log_min_duration_statement に秒数を設定する。 指定された時間以上に時間がかかる SQL がログに出力される。
インデックスの使用状況を調べる。
pg_stat_user_indexes にインデックスのアクセス状態が保存される。
SELECT indexrelname , idx_scan , idx_tup_read , idx_tup_fetch FROM pg_stat_user_indexes;
indexrelname
インデックス名
idx_scan
インデックスに対してスキャンされた回数。0 の場合は未使用のインデックス。
idx_tup_read
スキャンされたインデックスキーの数。
idx_tup_fetch
実際にインデックスキーからテーブルのレコードが読み取られた数。
PostgreSQL の浮動小数計算で、JDBC 経由だと計算結果が異なる。
Java の Double.parseDouble による誤差が原因。
psql で実行。
SELECT 7.0 / 3.0;
?column? -------------------- 2.3333333333333333 (1 row)
JDBC 経由で実行。
- 8.4-702.jdbc3
- 8.4-702.jdbc4
Class.forName("org.postgresql.Driver"); Connection con = DriverManager.getConnection("jdbc:postgresql://HOST/DB", "USER", "PASSWORD"); Statement st = con.createStatement(); ResultSet rs = st.executeQuery("SELECT 7.0 / 3.0"); if (rs.next()) System.out.println("Result: " + rs.getDouble(1));
2.3333333333333335
Double.parseDouble を実行。
System.out.println(Double.parseDouble("2.3333333333333333"));
2.3333333333333335
浮動小数では表せない数値?どちらも IEEE 754 浮動小数点のはずだが・・・
複数行作成する。
1 から 5 の数字データを作成する。(WITH RECURSIVE)
WITH RECURSIVE t(n) AS ( VALUES(1) UNION ALL SELECT n + 1 FROM t WHERE n < 5 ) SELECT n FROM t;
n --- 1 2 3 4 5 (5 行)
1 から 5 の数字データを作成する。(generate_series)
SELECT generate_series(1, 5);
generate_series ----------------- 1 2 3 4 5 (5 行)
2 から 10 の偶数データを作成する。
SELECT generate_series(2, 10, 2);
generate_series ----------------- 2 4 6 8 10 (5 行)
2010/3/1 から 2010/3/8 の日付データを作成する。
SELECT generate_series('2010-03-01'::Date, '2010-03-08'::Date, '1 days');
generate_series ------------------------ 2010-03-01 00:00:00+09 2010-03-02 00:00:00+09 2010-03-03 00:00:00+09 2010-03-04 00:00:00+09 2010-03-05 00:00:00+09 2010-03-06 00:00:00+09 2010-03-07 00:00:00+09 2010-03-08 00:00:00+09 (8 行)
1 から 5 の数字とその 2 乗のデータを作成する。
SELECT n.no, n.no * n.no AS sq FROM generate_series(1, 5) n(no);
no | sq ----+---- 1 | 1 2 | 4 3 | 9 4 | 16 5 | 25 (5 行)
カンマ区切りの文字列をカンマで分割し複数行データを作成する。
SELECT regexp_split_to_table('aaa,bbb,ccc', ',') AS d;
regexp_split_to_table ----------------------- aaa bbb ccc (3 行)
インデックスを強制的に使用する。
パラメータを設定する
- enable_seqscan
- enable_nestloop
インデックスを使用する場合「off」、戻す場合「default」
SET enable_seqscan = off; SET enable_nestloop = off;
パラメータを確認する。
SELECT * FROM pg_settings;