postgresqlサーバーのチューニングについて

このQ&Aのポイント
  • postgresqlサーバーのチューニング方法について解説します。
  • WANからVPNを経由して接続した状態でSELECTを行うと結果が帰ってくるまでに時間がかかります。
  • SELECTする際にbool型のフィールドを条件にすると時間がかかる理由について説明します。
回答を見る
  • ベストアンサー

postgresqlサーバーのチューニングについて

現在、Access2010+Postgresqlにてシステムを構築しており ADOにてデータベースからレコードの検索・追加・更新を行っております。 今回質問させて頂きましたのはpostgresqlのチューニング方法についてです。 現在、あるテーブルにWANからVPNを経由して接続した状態でSELECTを行うと、 結果が帰ってくるまでにおよそ6分程度かかるテーブルがあります。 (LAN内では4秒程度) 抽出するフィールドを*ではなく、1フィールドに限定しても約4分程度かかります。 そのテーブルには約30000件ほどレコードが格納されており SELECTする際は、bool型のフィールドをWHERE条件に入れています。 例)SELECT * FROM tbl_test WHERE f条件 = TRUE; しかし同じテーブルの別のvarchar型フィールドにLIKE演算子で検索を かけると、すぐ(0.44秒)に結果が帰ってきます。 例)SELECT * FROM tbl_test WHERE 名称 LIKE '%テスト%'; 尚、この場合の結果は20件ほどですので、結果が早いのは当然ですが なぜbool型を条件にした場合に6分もかかってしまうのでしょうか。 システムの都合上、WANからVPNを経由してアクセスする事が必須ですので LAN内の速度が速くてもWANからの速度が遅いのはNGなのです。 一応、Web上で紹介されている一般的なチューニング方法を参考にし postgresql.confの設定値は下記の通りに行いました。 ・shared_buffers → 1024MB ・max_connections → 100 ・effective_cache_size → 512MB ・random_page_count → 2 ・work_mem → 3MB 恐らく根本的にどこかの設定や設計がまずい為、このような結果に なっているのであろうと思うのですが、それを特定するに至りません。 見直すべき点やアドバイスなどがあれば教えて下さい。 <サーバースペック> OS:WindowsXP Pro SP3 メモリ:3GB CPU:Pen4 2.8GHz Postgresqlバージョン:8.3

  • SOU48
  • お礼率35% (51/144)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

なんとなくですが、チューニングでどうにかなるレベルの話じゃなくても、設計の問題のように思えます。 SELECT * FROM tbl_test WHERE f条件 = TRUE; のSELECT自体が遅いのではなく、その結果をパケットデータにして、 VPN経由でMS-ACCESSに転送する部分が重いのではないでしょうか? つまり、SQLのリザルトデータが大量すぎるのが問題なので そのリザルトを使ってさらにMS-ACCESS側でさらに絞り込んでいるのなら そのロジックをACCESSからSQL側に移転させれば、一気に 解決できるように思われます。 たとえば、 更新時は、更新する対象のデータのみを取り出すSQLにする。 挿入前の衝突チェックなら、衝突チェックをACCESS側でなく衝突チェック用のSQLを投げる。 一覧表示なら、ページ分割にして limit句で部分取り出しにする。 データ検索も、ACCESS側でなくSQLで実装する。 といった具合に。

SOU48
質問者

補足

早々のご回答、誠に有り難うございます。 なるほど、チューニング云々の問題ではなさそうとの事ですね。 確かに「検索に時間がかかる」というよりかは、 データの受け取りに時間がかかっているような気はしていました (LAN内では3秒程度なので) 回答者様のおっしゃる通りかと思います。 ただ、やはりAccess側に最高で30000件程度のデータを表示させる事は 避けられませんので、別の角度からデータの受け取りについて考えてみる必要がありそうですね。 有り難うございました。

その他の回答 (1)

回答No.2

どうしても、MS-ACCESS側に全データを取り込んでおく必要があるというのなら (あまり綺麗な方法ではないですが) 毎回大量のリザルトがあるSQLを発行するのではなく、データをACCESS側にキャッシュしておいて、 更新・挿入・削除のあったデータのみをもってきてローカル側で整合させるって方法もありえますね。 これはこれで、アルゴリズムしっかり考えないと、同期とれなくなって データ壊してしまう可能性もありますが。 それを考えると、MS-ACCESSのあるLAN側にもPostgreSQLを立てて、 PostgreSQL同士でレプリケーションを組んでしまったほうが、簡単かもしれません。 もし、PostgreSQL とMS-ACCESSとでレプリケーションが組めるような パッケージなりライブラリがあるなら、そっちを使う方法もあるでしょうけど。

SOU48
質問者

お礼

なるほど、ローカル側にキャッシュする方法もありですね。 もちろんご指摘の整合性を保つ問題はありますが・・ あれから色々とLAN内で試しましたが、どうやらLAN内では そこそこの速度で結果が帰ってきましたので、やはりpostgresqlそのものの 問題ではなさそうな気がしてきました。 ご回答頂きました方法も合わせて、データ保持の方法について もう一度考えてみたいと思います。 有り難うございました。

関連するQ&A

  • PostgreSQLの「*」について・・?

    こんにちわ, 今PostgreSQLを勉強しています。 たとえば, SELECT * FROM table where field ~ 'a'; とすると,tableテーブルからfieldに「a」が入っている項目を抜き出す,となります。 これに SELECT * FROM table where field LIKE '*a'; とすると,エラーが出てしまいます。 *(ワイルドカード)の使用はどのようなときに使用するのでしょうか。PostgreではLinuxとは違う使用をすると書いてあったのですが,よくわかりません。 よろしくおねがいします。

  • PostgreSQLでサブクエリーをJOINする方法

    たとえば、 select A.field1, B.field1 from (select field1 from table1 where field2='x') A, (select field1 from table2 where filed2='y') B where A.field2=B.field2; のようなことをしたいのですが、 Oracleだとこの方法でデータを取ってこれるのですが、PostgreSQLだとエラーで返ってきてしまいます。 PostgreSQLのバージョンは6.5.3です。 バージョンが上がると上記の書き方も通るようになるのでしょうか? また、上記の書き方と同じ意味を持つ他の書き方をご存知でしたら教えてください。よろしくお願いします。

  • postgreSQLで分からないことがあります。

    postgreSQLで分からないことがあります。 よろしくお願いします。 下にあるtblというテーブルがあったとき。 下のSQLを実行するとデータがうまく取れているんですが、 CURRENT_DATEは日付型でSUBSTRでとりだした日付は文字列 なのに何故正しく比較できているのでしょうか? 日付型の形式の文字列であれば、RDBMSがかってに日付型にしてくれるのでしょうか? tblテーブル *sdateとedateはtimestamp型です。 sdate      | edate | ----------------------------------------- 2010-5-1 10:00:00 | 2010-5-2 13:00:00| SELECT * FROM tbl WHERE CURRENT_DATE BETWEEN SUBSTR(sdate, 1, 10) AND SUBSTR(edate, 1, 10)

  • PostgreSQL 7.2.8 異なるデータベース間のテーブル

    こんにちは。かなり困っています、よろしくお願いします>< PostgreSQL 7.2.8 を使用しています。 一つのユーザーで、二つのデータベースがあります。 それぞれ同じカラムを持つ同じ名前のテーブルがあります。 中のデータは違います。 db1 - tableT db2 - tableT 条件を付けて、db1のtableTのデータを db2のtableTへコピーするにはどのような方法がありますか? 例えば select * from db1.tableT tbl1, db2.tableT tbl2 where tbl1.title = tbl2.title; のようにしてとりあえずselectで試してみましたがダメでした。 やはりスキーマとデータベースは違うんですね>< ドットが認識されませんでした。 どなたか解決法をご存知の方、よろしくお願いします。

  • postgreSQLで更新後のデータを取得したい。

    postgreSQLで更新後のデータを取得したい。 初めて質問させていただきます。 postgreSQLでupdateした後、更新後のデータをselectで取得したいのですが、 トランザクションが完了するまでにselect文が発行されているみたいで、更新前のデータを取得してしまいます。 それぞれ、違うファイルから投げられているので、同じトランザクションにすることはできません。 何かいい方法があればご教授お願いします。 a.phpで下記のSQLを発行 update test_tbl set test1 = 'aaa' where test2 = 'bbb' a.phpが走っている間に、下記のb.phpが実行される。 select test1 from test_tbl 環境 php5 postgres8.1

  • 別のサーバーにあるDBに対してSELECTした結果が帰ってこない。

    別のサーバーにあるDBに対してSELECTした結果が帰ってこない。 質問はタイトル通り、別のサーバーにあるDBに対してSELECTした結果が帰ってきません。 あるwebサイトを新しいサーバーに移行する事になりました。 データベースはwebサイトと同じサーバーに準備していたのですが 新しいサーバーに移行する際に別のサーバーに準備する事になりました。 そして新しい環境で動作検証をしていて特に問題なく進んでいたのですが・・・・ 旧環境では特に問題なくSELECTした結果が帰ってきていましたが 新しい環境ではデータ取得の際に件数が多くなるとSELECTした結果が帰ってきませんでした。 SELECTした結果は約7000件~30000件のデータを取得するようになっております。 (新しい環境で1000件近くのデータを取得しようとしたら約5分かかりました。) これはSQL文が悪いのでしょうか、それともphpの設定が悪いのか、postgresqlの設定が 悪いのか特定出来ずに困り果てております。。。 何でも構いませんのでご助言を頂けたら幸いです。 ■環境について □以前の環境 同じサーバー内にphpとpostgresqlがある Postgresqlのバージョンは8.0.3で、phpのバージョンは5.0.5です。 □現在の環境 別のサーバーにphpとpostgresqlがある Postgresqlのバージョンは8.1.18で、phpのバージョンは5.1.6です。 ■データ取得テーブル □テーブル名 テストテーブル □フィールド数 100 (登録時刻フィールドはタイムスタンプ型です) □SQL文例 Select * From テストテーブル Where 登録時刻フィールド >= 'yyyy-mm-dd' AND 登録時刻フィールド <= 'yyyy-mm-dd'

  • PostgreSqlについて

    おはようございます。 質問させてください。 テーブルのカラムにtimestamp型のフィールドがあるとします。 テーブルinsertの時に現在の時間をいれたいのですが、どのような値を入れればいいのでしょうか? test_tbl-------------- ID:INTEGER DATE:TIMESTAMP ---------------------- insert into test_tbl (ID, DATE) values (1, ****); ****の部分にnow, dateとかそんな関数はあるのでしょうか?

  • PostgreSQLの言語設定について

    サーバーOS:ターボ10 クライアントOS:winXP DB:PostgreSQL 7.4.5 エミュレータ:Tera Term Pro version 2.3 この場合、PostgreSQLのエンコードは何がいいですか? やりかたはどうすれば良いですか? Tera Termのエンコードは一応SJISにしようかと漠然と思いましたがEUCの方がいいですか? サーバー自体のエンコードは何か設定必要ですか? (1)winXPからTera Termでターボ10に搭載したポスグレのテーブル項目に日本語をインサートし、そのテーブルをODBC経由でwinXPのアクセスでブラウズする。 サーバー操作 create table tbl1 (item1 char(10)); insert into tbl1 values('あいうえお'); PC操作 アクセスでブラウズ (アクセスの接続は解決済み) (2)winXPのアクセスでODBC経由のポスグレのテーブルを編集した後、Tera Termでターボ10に搭載したポスグレのテーブル項目に日本語の検索をかける。 PC操作 アクセスで'かきくけこ'を挿入。 サーバー操作 select * from tbl1 where item1 like'か%';

  • データベースのワイルドカードは%ではないの?

    アクセスのテーブルに あ い う があり、 SQL文で *********************************************** SELECT テーブル1.フィールド FROM テーブル1 WHERE (((テーブル1.フィールド) Like "%あ%")); *********************************************** としてもエラーにならないけど、「あ」が抽出されません。 *********************************************** SELECT テーブル1.フィールド FROM テーブル1 WHERE (((テーブル1.フィールド) Like "*あ*")); *********************************************** にすると、「あ」が抽出されます。 アクセスなどのデータベースのワイルドカードは%だと思っていたのですが違うのですか?

  • SQL文にて・・・

    質問があります。PostgreSQLです。 テーブル(test_tbl)があるとします。 テーブル構成は --------------------------- id ===== char(16) [英数文字格納] point ==== int2 add_date ==== timestamp --------------------------- このテーブルから idが2文字目から'di6ek68dh5ls7g'のレコードを取得したいと考えています。 レコード数がかなりおおいので パフォーマンスを重視したいのですが、 検索SQLがわかりません。 select * from test_tbl where id like '%di6ek68dh5ls7g'だとでると おもうのですが、 これ以上にパフォーマンスがあがる SQLがわかる方お願いいたします。