- - PR -
巨大なテーブルの結合、業務アプリの統合
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-09-13 15:39
現在稼働中のシステムですが
WebLogic6.1sp6 PostgreSQL-7.3.6 でWebアプリーケーションを作成しました。このシステムは既存のシステムのリプレース だったので過去約5年間分のデータがありました。勿論すべてのデータが移行の対象 でPostgreSQLに移行はできたのですが、いかんせん件数が多すぎて検索に時間がかかり 過ぎてしまいます。(5年間で約150万件) 5年間のデータが常に必要かと言えばそうでもない、よく使うのは最近の1年分、 1年経過分は無いと困るが、さほど頻繁に使うものでもない・・・と言う状況で PostgreSQLのデータは1年以内と1年経過分で分割しました。 月次処理で1年以内のテーブルから1年経過分のテーブルにデータを1ヶ月単位で 移動させています。 DBのほうはこれでよかったんですが、困ったのはWebアプリケーションの方です。 上にも書いた通り1年経過分も頻繁には参照しないが、無いと困るという要望 なので、しかも対応にかけられる時間が限られていたこともあり、不本意ではあり ますが、EntityBeanと業務をまるまるコピーして名前を変えて1年経過分を参照 する業務を作ってしまいました。 オブジェクト指向、Javaのセオリーから言うと邪道であることは明らかですが、 早急に対応が必要と言うことで、苦肉の策です。 今になって、これが色々と足を引っ張るようになり、この分けた業務を統合でき ないものかどうかと考えています。 分割したテーブルはテーブル名が違うだけでカラム定義は全く同じです。 考えられる方法として 1)PostgreSQLでViewとRuleを定義し、2つのテーブルをアプリ側からは あたかもひとつのテーブルのように見せる 2)Entity-Beanの中で吸収し、2つのテーブルを業務側からはひとつのテーブル のように見せる という2つの案を考え出しました。 1)は機能的に、ほぼ思った通り実現できたのですが、若干、処理時間が延びてしまいます。いままでは片方のテーブルしか参照しなかったのが2つのテーブルを参照するように なったので、これは仕方ないかと思います 2)は検索メソッドに引数を増やしてどっちのテーブルを検索対象にするかを指定 してやろうと思ったのですが、EntityBeanのejbFindByPrimaryKeyメソッドが どうやらprimary-key classのみしか指定できないようで、引数を増やすとデプロイ でエラーになります。 処理速度を犠牲にしないで、この分けた業務を統合するのにはどういう解決方法 があるのでしょうか? | ||||||||
|
投稿日時: 2004-09-13 16:42
オブジェクト指向とかアプリケーションうんぬんじゃなくて、データベース設計として間違ってるよ。当年分だけを切り出しておくという発想がアホ。 | ||||||||
|
投稿日時: 2004-09-13 16:54
PostgreSQL に詳しくないので、上で言う Rule がどういったものかわかりませんが、 Oracle の Partitioning Option は、上記1)に考え方は近いものと思います。 | ||||||||
|
投稿日時: 2004-09-13 17:33
アホ言われようがなんと言われようが、150万件1テーブルでは当時の PostgreSQL-7.1.2(今はアップデートして7.3.6)ではシステムの停止時間内に VACUUMが終わらなかったので、この方法しかありませんでした。 設計的にはそりゃー1テーブルが理想ですが、性能的にはムダです。 | ||||||||
|
投稿日時: 2004-09-13 17:39
[quote]
ボアさんの書き込み (2004-09-13 16:54) より:
おそらくPostgreSQL独自の機能だと思います。通常のViewは更新できませんが、 ViewにRuleを定義してあげることによってViewに対しinsert, update, delete が発行されたときに別の動作に置き換えてあげることができます。 これで見かけはviewだけど更新ができるviewが作れます。 テーブルを分割しなければならなかった理由は検索の処理時間もありますが、 1番の理由はVACUUMの処理時間です。業務開始時間になっても終わっていないことが 度々ありました。 | ||||||||
|
投稿日時: 2004-09-13 17:51
PostgreSQLって、テーブルスペースは使用できないんでしょうか?
私が設計しているシステムは、DBはDB2ですが、 仕様上、ユーザーが属するグループ毎にテーブルスペースが分かれています。 ユーザーの情報をもつテーブルも、各テーブルスペース毎に持っているため、 ログイン時に、テーブルスペースのIDを入力させ、 それをセッションで引き継ぐ構造になっています。 テーブルスペースが異なるので、ログイン後は、 各々のDBを参照しに行くようなものです。 この構造、好きではないのですが、ユーザーさんの要求仕様なので、 こちらとしては従うしかありません・・・。 私はログイン時に、テーブルスペースのIDを入力させるなんて、 聞いたこともみたこともありません。 | ||||||||
|
投稿日時: 2004-09-13 18:01
テーブルスペース(Oracleにもあったような・・・)という概念はありません。 先にも書いたとおりVACUUMの処理時間が業務開始時間になってもおわっていなかった のが最大のネックでした。7.3.6になってからは信じられないくらい、目を疑うくらい あっという間に終わってしまいます。 最初から7.3.6だったら、こんなことしなくても済んだんでしょうが、当時は7.1.x が最新だっだので・・・ | ||||||||
|
投稿日時: 2004-09-13 18:19
[quote]
彷徨える開発者さんの書き込み (2004-09-13 17:39) より:
こんにちは、がちゃぴんです。 横道にそれるかもしれませんが、ちょっと前の@ITのニュースにこんなのがありました。 こんな記事を見た覚えがあるってだけで書いてます。全く意味が無かったらごめんなさい。 http://www.atmarkit.co.jp/news/200408/26/oracle.html 記事の中盤以降にPostgreSQLのアーキテキチャや基本やら書かれていますが、 既に出来上がっているシステムに対してはあまり意味はありません... その後にパフォーマンスや運用時のことについて少し書かれています。 【記事引用】 ・PostgreSQLでパフォーマンスや信頼性を向上させるにはRAIDの利用など ハードウェアで対応するしかないという。 ・PostgreSQL 7.2以降はデータをロックせずに使用済み領域を再利用できる コンカレントVACUUMが導入されたが、コンカレントVACUUMではデータファイル 自体は縮小せず、やはりデータをロックするFULL VACUUMを定期的に実行する必要がある。 FULL VACUUMをする必要があると書かれ、試しているわけではありませんが、 時間の無い時はコンカレントVACUUMでやってもやはり意味とかはないですかねー... | ||||||||
