サンプルコード若しくは解決に至りそうなウェブサイトを教えてください。


CGI(Perl)でコーディングしたプログラムです。
CGIが動作するマシンとPostgreSQLサーバが動くマシンは別々で、TCP/IP接続(LAN)です。

PostgreSQLサーバにDBD::Pgでアクセスし、select文を送ります。
一件ずつ検索を行い、一致したら変数に代入するというものです。

データベースが増大するごとに、先頭行から検索しているため時間がかかっています。
検索スピードを向上させたいのです。

当方の組み込んだコードです。

>>

use DBI;
$db = DBI->connect("DBI:Pg:host=$host;dbname=$dbname", $user, $passwd) || die "DBI connect failed : $DBI::errstr";

#テーブルを開く
$st = $db->prepare("select * from tablename");
$res = $st->execute;

#テーブル処理
while (($aaaaa,$bbbbb)=$st->fetchrow_array){
if ($aaaaa =~ /$query/){
$answer = "$bbbbb";
last;
}
}

<<

お力を貸してください。

回答の条件
  • URL必須
  • 1人1回まで
  • 登録:
  • 終了:2008/10/25 13:23:28
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:kn1967 No.1

回答回数2915ベストアンサー獲得回数301

ポイント100pt

一番ネックとなっているのは

(1)全フィールドを取得 → Perl側で絞り込み

という流れにしている点があげられると思いますので

(2)フィールド名を取得 → 必用なフィールドだけを取得

という流れに変えれば

(a)perl側でのレコード毎処理ではなくPostgreSQL側での一括処理

(b)2台のコンピュータ間を流れるデータ量を格段に落とす

による高速化が期待できます。


そもそも、Perl側で絞り込んでいるのは

正規表現を使う必要があるためだと思いますが

PostgreSQL側でも正規表現を使った絞込みが可能ですから利用しない手はありませんし、

もしも非常に簡単なものであるならばLIKE演算子が使えるかもしれません。

(下記は例として少し古めのバージョン8.03のマニュアル)

http://www.postgresql.jp/document/pg803doc/html/functions-matchi...


SQL発行は二段階になりますが

まずは、システムカタログから正規表現でフィールド名を取得するSQL

SELECT attname
FROM pg_attribute
WHERE attnum > 0
    AND attrelid = (SELECT relfilenode FROM pg_class WHERE relname = 'テーブル名')
    AND attname ~ '正規表現'
LIMIT 1;

システムカタログについては下記参照ください。

http://www.postgresql.jp/document/pg803doc/html/catalog-pg-attri...


次に、上記で取得したフィールド名で情報を元にしてフィールド内の情報を得るSQL

SELECT 上記で得たフィールド名 FROM テーブル名

という流れがよろしいかと思いますがいかがでしょう。

id:cabeliau

kn1967 様

ご回答ありがとうございます。非常に参考になりました。早速組み直してみます。

2008/10/25 13:22:45

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません