3

Perl を使用して 2 つの html テーブルを作成しています (各テーブルは独自の Perl CGI スクリプトで生成されます)。SQL クエリを実行する「ヘルパー」スクリプトがあります。以下に例を示します (このスクリプトを と呼びましょうrun_sql_query.pl):

my $sql_query = "SELECT ID from TABLE where ID > 3";
our $sth = $dbh->prepare($sql_query);
$sth->execute;

次に、2 つの Perl CGI スクリプトのそれぞれで、次のことを行います。

require 'run_sql_query.pl';

our $sth;
while (my ($table_id) = $sth->fetchrow_array) {
...
}

ただし、run_sql_query.pl2 回実行されているようです (各 Perl CGI スクリプトで 1 回)。一度だけ実行され、両方の Perl CGI スクリプトでrun_sql_query.pl同じ内容を使用するようにするにはどうすればよいですか?$sth

4

3 に答える 3

7

私の理解が正しければ、クエリの結果を保存して、別のプロセスで再度使用できるようにしたいと考えています。これにはいくつかの方法がありますが、いずれもある種のキャッシュを設定する必要があります。

CGI プロセスには別のメモリがあるため、要求したことを直接実行することはできません。さらに悪いことに、それらはリクエストごとに開始および停止され、コンパイルに多くの時間を浪費します。ただし、それを回避する方法はたくさんあります。

SQL クエリが高価で、データが頻繁に変更されない場合は、データベースに結果をキャッシュさせることができます。たとえば、MySQL キャッシュは次のとおりです。これには、データベースを使用するすべてのものがそれを使用するという利点があります。欠点は、プログラムがすべてのデータを取得して処理する必要があることです。これを使用すると、クエリは高価ですが、フェッチと処理はそれほど高価ではなく、データは頻繁に変更されません。

もう 1 つのオプションは、 memcachedなどの外部キャッシュを設定して、結果を保存することです。Memcached は基本的に、データの大きなハッシュを格納するマシン上のサーバーです。または、データベース自体を使用して、処理された HTML テーブルをキャッシュすることもできます。各プロセスは、自分で計算する前に、必要なデータがキャッシュにあるかどうかを確認できます。CHIのようなものを使用して、それとやり取りすることができます。利点は、必要なものを何でもキャッシュに入れることができることです。欠点は、自分でキャッシュを管理しなければならないこと (つまり、データがなくなったときにデータを削除すること) であり、別の管理が必要であり、キャッシュはいつでも消える可能性があります。

最後に、プロセスの実行方法を変更できます。基本的な効率向上は、要求ごとにプログラムを開始、コンパイル、実行、および終了する単純な CGI から、独自の小さなサーバーでプログラムを実行するFastCGIのようなものに変更することです。whileプログラム全体にループを配置するようなものだと考えてください。プログラムは各リクエスト間でシャットダウンしないため、データをグローバル変数に保存できます。次に、@foampileが提案したことを実行したり、テーブルを保存しour @Table_Cacheたりするのは簡単なことです。これにより、そのプロセスではキャッシュされますが、他のプロセスではキャッシュされません。それぞれの異なるプログラムは、独自のプロセスです。だからfoo.cgi共有しないbar.cgi. 利点は簡単なことです。FastCGI はとにかく切り替える必要があり、Web サーバーはおそらく既にサポートしています。欠点は、キャッシュを管理する必要がある (つまり、古いエントリを削除する) ことと、プロセス間で共有されないことです。

FastCGI から始めて、パフォーマンスの問題が解決するかどうかを確認します。これは、リクエストごとではなく、サーバーの再起動ごとに各クエリを2 回だけ実行することを意味します。

于 2012-10-15T21:44:38.927 に答える
1

最初にレコードセットを反復処理するときに、クエリ結果をハッシュのハッシュまたはデータ構造にフィードする必要があります。その後は、ハッシュ/構造を通過または参照するだけです。

my $dataStruct;

while (my ($table_id) = $sth->fetchrow_array) { 
     my $colVal = $sth->data[...];
     $dataStruct->{$table_id}->{'col'} = $colVal;
} 

その後、$dataStruct を反復処理します。その方法の説明が必要な場合はお知らせください。

于 2012-10-15T21:14:54.097 に答える
-1

プロセス間 (またはスレッド間) で Perl 変数を真に共有する方法はありません。

しかし、できたとしても、コンセプト全体が意味を成しません。データベースは 2 つのクライアントと通信していることを知る方法がないため、1 つのクライアントが一部のレコードを取得し、もう 1 つのクライアントが残りの一部を取得することになります。

データを 2 回取得する必要があります。データを中間の場所に保存し、そこから 2 つのクライアントにフェッチさせることもできますが、その必要性は示されていません。

于 2012-10-15T21:46:29.493 に答える