10

私たちのアプリは現在、次のように動作します。

class myClass{

    private $names = array();

    function getNames($ids = array()){
         $lookup = array();

         foreach($ids as $id)
             if (!isset($this->names[$id]))
                $lookup[] = $id;

         if(!empty($lookup)){
              $result;//query database for names where id in $lookup
                      // now contains associative array of id => name pairs
              $this->names = array_merge($this->names, $result);
         }

         $result = array();
         foreach($ids as $id)
             $result[$id] = $this->names[$id];

         return $result;
    }
}

これは正常に機能しますが、いくつかのクエリ (この例では 400 以上) が発生する可能性がある (そして頻繁に発生する) ことを除きます。

そのため、単純にデータベースにクエリを実行し、$this->namesデータベースのすべての名前を配列に入力することを考えています。

しかし、これを行うときにメモリを心配し始める必要があるデータベース内のエントリの数が心配ですか? (データベース列は varchar(100) です)

4

2 に答える 2

7

どのくらいのメモリを持っていますか? また、アクセスのピーク時にサービスが一般的にサポートする同時ユーザー数は? これらは関連する情報です。それらがなければ、どんな答えも役に立ちません。一般に、これは負荷テストで簡単に解決できる問題です。次に、ボトルネックを見つけて最適化します。それまでは、(理にかなった範囲で)動作させるだけです。

しかし ...

自分が見ているもののアイデアを本当に知りたい場合は...

マルチバイト文字を保存していないと仮定すると、400 個の名前 * 100 文字 (すべての名前が文字制限を超えていると仮定) があり、最大 40Kb のメモリが必要になります。心配するにはあまりにも取るに足らないようですね。

明らかに、データ構造自体を保持するために PHP から他のオーバーヘッドが発生します。SplFixedArrayプレーンの代わりに のようなデータ構造を使用して、より効率的に物事を保存できますarrayか? array_*おそらく - しかしそうすると、そうでなければリストを操作する必要がある高度に最適化された関数が失われます。

ユーザーは、メモリにバッファリングする予定のすべてのエントリを使用しますか? アプリケーションにそれらが必要な場合、それらがどれほど大きいかは問題ではありませんよね? 「ただの理由で」必要のない多くの情報をメモリに保持することはお勧めできません。絶対にやりたくないことの 1 つは、ページの読み込みごとにデータベースに 4000 レコードのクエリを実行することです。少なくとも、これらのタイプのトランザクションを memcached などのメモリ ストアに配置するか、APC を使用する必要があります。

この問題は、コンピュータ サイエンスのほとんどの問題と同様に、単純に制約付き最大化問題です。自由に使える変数を知らなければ、正しく解くことはできません。

于 2012-08-29T04:29:53.320 に答える
3

1000 以上のアイテムを取得すると、キー付きのルックアップが非常に遅くなります (特定のキーにアクセスするときに遅延が発生します)。ksort() で修正できます。(ksortを追加するだけで、スクリプトの実行時間が15分から2分未満になるのを見ました)

それ以外は、実際にはメモリによってのみ制限されます。

より良い方法は、不足しているデータの配列をスクリプトで作成し、IN リストを使用して 1 つのクエリでそれらすべてをフェッチすることです。

あなたがそれを助けることができるなら、ユーザーが決して見ることのないデータを格納するメモリを無駄にすべきではありません。

于 2012-08-29T04:30:12.010 に答える