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;
}
}
<<
お力を貸してください。
一番ネックとなっているのは
(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 テーブル名
という流れがよろしいかと思いますがいかがでしょう。
kn1967 様
ご回答ありがとうございます。非常に参考になりました。早速組み直してみます。