- 締切済み
単純なselectが遅くなるのですが、理由がサッパリわかりません
初めて投稿させて頂きます。 過去に、PostgreSQL 7.4.6(Linux 2.6.9-5.EL)の環境で、データ監視系のシステムを構築しました。稼働してから数年が経過しています。 このシステムのDBには数十のテーブルがあり、期待通りに動いています。 ただ、一つのテーブルのみ、時間が経過の経過と共にselectが恐ろしく遅くなる現象が発生しています。 そのテーブルのスキーマは以下です。 =# \d node_condition; Table "public.node_condition" Column | Type | Modifiers ------------------+-----------------------------+----------- node_id | integer | checktime | timestamp without time zone | ping | boolean | rtt | real | cpu | real | loadavg | real | mem | real | disk | real | snmp_w | integer | ip_w | integer | serv_w | integer | licence | integer | f_licence | integer | version | text | web_ver | text | sync | boolean | errchecktime | timestamp without time zone | ipwatchtime | timestamp without time zone | servwatchtime | timestamp without time zone | nmsdlasttime | timestamp without time zone | filemakelasttime | timestamp without time zone | 現在入力されているデータ数は51ラインです。 設計上、このテーブルは約1分間に51回updateが行われます。 主に時間系の更新です。 他のテーブルと違うところは、カラム数が少し多い、updateが頻繁に実行される、というくらいです。他のテーブルは多くても12カラムで、子のような現象は出ていません。 SQL(select)は至ってシンプルで、このテーブルしか参照しません。(select node_id,checktime ... from node_condition;) 構築時の応答速度は至って普通だったのですが、昨年の夏に異常に遅くなっていることが判明しました。 その時は、データを退避してからテーブルをDROPしてcreateし直すという荒業で解決したのですが、先日また異常に遅くなっている事に気づきました。 (この時点で原因を潰すべきだったのですが、忙しくて強引にやってしまいました。ちなみに、その時VACUUM,ANALYZEはやったのですが、効果がありませんでした。また、このシステムではVACUUM,ANALYZEが定期的に実行されています。) postgresはupdateのアルゴリズムは、他のRDBMSと違うような事が書いてありましたが、カラム数が多くなると挙動に影響が出るのでしょうか。どなたか詳しい方がいましたら、ご教授頂けると助かります。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- yamada59
- ベストアンサー率74% (29/39)
定期的にVACUUMを実行しているにも係わらず、時間の経過とともに51件しかデータの格納されていないテーブルのSELECTが遅くなるとしたら、空き領域マップ(FSM)のページ数が不足していることが原因として考えられます。 FSMのページ数が不足していると、VACUUMを実行してもUPDATEで発生したゴミの領域を再利用できるようにならず、どんどんテーブルファイルが大きくなって性能が低下します。 VACUUMの実行時にVERBOSEオプションを指定すると、必要なページ数が表示されます。そのページ数がpostgresql.confファイルのmax_fsm_pagesパラメータの値よりも大きければビンゴです。 max_fsm_pagesパラメータの値を大きくして PostgreSQL を再起動し、テーブルを再作成してデータをリストアしなおすか、VACUUM FULLでテーブルファイルのサイズを小さくしてください。そうすれば性能が改善されるかもしれません。
- chukenkenkou
- ベストアンサー率43% (833/1926)
質問内容が、漠然としすぎです。 >ただ、一つのテーブルのみ、時間が経過の経過と共にselectが恐ろしく遅くなる >構築時の応答速度は至って普通だったのですが、昨年の夏に異常に遅くなっていることが判明 「恐ろしく遅い」、「普通だったが、・・・異常に遅くなった」などと書かれても、具体的な説明なしに他人にアドバイスできると思いますか? >現在入力されているデータ数は51ラインです。 >設計上、このテーブルは約1分間に51回updateが行われます 51ラインとは? 母体データが51件と、言っている訳ではないのですよね? 51回updateとは、母体データ何件に対し、何件のupdateを何回やると言ってますか? どんな検索条件を指定し、どの列をどのようにupdateするのでしょうか? >SQL(select)は至ってシンプルで、このテーブルしか参照しません。(select node_id,checktime ... from node_condition;) 検索条件なしで、全件検索をやると言ってますか? 関数の使用、order by、distinctやgroup byなどもないのですか? 時間の経過と伴に性能劣化するなら、普通に考えればインデクスを有効利用できていないのでしょうが、提示された内容から判断は無理です。
補足
すみません・・・ 説明がなってませんよね。 まず、「恐ろしく遅い」ですが、構築時はクエリ完了までに0.0secで返ってきていたのですが、運用するにつれて20.0sec程度掛かるようになっています。 次にテーブルについてですが、現在51件入力されている状態です。 この51件のデータには、それぞれIDが付いていて、その51件に対して1分間に1回ずつupdateされるようになっています。具体的には、 update node_condition set checktime = '2010/02/10 10:01:00' where node_id = 1; です。 selectは検索条件無しです。本当に初心者本の最初に載っているようなselect文です。ソート系やプロシージャも無しです。 INDEXも使っていません(51件程度しか入らないテーブルなので) というように幼稚な設計部分なので、この現象自体が逆に不思議なのです。SQLの組み直しをする余地も無いんです。 なので、postgres側に何か重大な欠陥でもあるのかなと思って皆様のお知恵をお借りしようと思った次第です。 拙い説明で申し訳無いですが、アドバイス頂けると幸いです。
お礼
ご回答ありがとうございます。 稚拙な質問文にもかかわらず、適切なご意見を頂きまして恐縮です。 FSMのページ数ですか、、、初めて聞きました。 この辺のパラメータは知ってからDBMSを使え!って怒られそうですけど・・・ 今度現場に行った時に調査して見ます。 少し時間が空くかもしれませんが、必ず結果をご報告します。