2009-07-30 15 views
1

アプリケーションコードにレコードIDの配列がある場合、データベースからレコードを読み取る最も良い方法は何ですか?あなたはn個クエリを行うためデータベースからレコードIDの配列を取得した複数のレコードを効率的に読み取る

$idNumsIWant = {2,4,5,7,9,23,56}; 

明らかに各IDをループは悪いです:

foreach ($idNumsIWant as $memID) { 
    $DBinfo = mysql_fetch_assoc(mysql_query("SELECT * FROM members WHERE mem_id = '$memID'")); 
    echo "{$DBinfo['fname']}\n"; 
} 

ので、おそらくそれは、単一のクエリを使用して良いですか?

$sqlResult = mysql_query("SELECT * FROM members WHERE mem_id IN (".join(",",$idNumsIWant).")"); 
while ($DBinfo = mysql_fetch_assoc($sqlResult)) 
    echo "{$DBinfo['fname']}\n"; 

しかし、この方法では、配列の要素数が30,000であるときにスケールされますか?

どのようにこの問題に効率的に取り組んでいますか?

答えて

1

私の考え:

第一の方法は、処理およびディスク読み込みの面でコストがかかりすぎるです。

2番目の方法はより効率的で、query size limitについて心配する必要はありません(とにかくチェックしてください)。

1

私は状況のようなものに対処する必要がある場合、私は、少なくとも3つのまたは4つの可能な解決策を参照してください。IDごと

  • つの要求を、あなたが言ったように、これは本当に良いことではありません。多くのIDS
    • のための1つの要求がありますが、IDSの非常に長いリストでそれを行うことはできません:いくつかのデータベースエンジンは数に制限があり、私は一般的に
    • はあなたが提案したソリューションを使用することを行いません。データのあなたは、だから私は、一般的にX IDの1つの要求のような何かを良好なパフォーマンスワイズ
    • ではないかもしれませんIN()IN()
    • 非常に大きなリストに渡し、これを繰り返すことができます。たとえば、1000のIDに対応するデータを取得するには、20個のリクエストを行い、それぞれが50個のIDのデータを取得します(これは単なる例です:DB /テーブルのベンチマークは、要因)いくつかのケースでは
  • 、あなたはまた、再考えることができ、あなたの要求:多分あなたは参加のいくつかの種類を使用することにより、IDSのようなリストを渡して避けるだろうか? は(これは本当にあなたが必要なものに依存して、あなたのテーブルスキーマ、...)また

、フェッチロジックの変更を容易にするため、私はIDのリストを取得する関数を記述し、戻りますそれらに対応するデータのリスト

このように、この関数を同じ方法で呼び出すだけで、同じデータが得られ、データの取り込み方法を気にする必要はありません。これは、何かを壊すことなく、必要に応じてフェッチメソッドを変更することができます(何らかの他のよりよい方法が見つかった場合):関数の動作は変わりますが、インタフェース(入出力)はそのままで、

1

私の場合、in節の値の大きなリストを持っていたら、必要な値を含む変数を持つストアドプロシージャを使用しますそれを一時テーブルに送信してそれに参加する機能です。送信したい値のサイズに応じて、複数の入力バラバラに分割して処理する必要があります。データベース内で値が永続的に保存される可能性がありますか?ユーザーはどのように30,000の値を選ぶだろうか、確かに彼または彼女はすべてであると思うだろうか?ですから、joinとwhere句に基づいてテーブルをクエリする方が良いでしょう。

2

最善のアプローチは、最終的には配列にあるIDの数に依存します(技術的には50MBのSQLクエリを送信したくないのは明らかですが、トラブル)がありますが、主にどのように結果の行に対処するかについてです。 IDの数が非常に低い場合

  • 完璧になりますのIN構文を使用してWHERE句を使用して、単一のクエリ(のは数千トップスをしましょう)。あなたのSQLクエリは、それが信頼性が高く、効率的かつ迅速にDBサーバに転送されるのに十分短いでしょう。このメソッドは、結果のレコードをループする単一のスレッドに最適です。

  • IDの数が本当に多い場合は、ID配列を複数のグループに分割し、IDのグループごとに1つ以上のクエリを実行することをお勧めします。 DBサーバーにとっては多少重くなるかもしれませんが、アプリケーション側では複数のスレッドを生成し、複数のレコードセットが到着するとすぐに対処することができます。

どちらの方法も有効です。

Cliffnotes:この種の状況では、データ抽出があまりにもボトルネックにならない限り、データ使用に焦点を当てます。あなたのアプリをプロファイルしてください!

0

StringTokenizerを使用すると、文字列をトークンに分割することで、複数の値のデータを取得することが容易になります。

関連する問題