検索

ホームページ  >  に質問  >  本文

PHP と MariaDB は、複数の挿入を実行するためのより効率的なソリューションを提供できますか?

そこで私は、リーグ内のピンボール マシンのハイスコアを追跡するための小さなデータベースを構築しようとしています。 AI ID 列と電子メール アドレスを含む列のみを持つユーザーのテーブルがあります。次に、AI ID 列とマシンの名前であるゲーム テーブルがあります。これは多対多の関係であるため、user_id、game_id、および Score を列として含む「scores」という 3 番目のテーブルを作成しました。

編集: 読み取りコードを含めます:

リーリー

同様のコードを使用して、ゲームがデータベースにすでにリストされているかどうかを確認します。ゲームの ID 番号と 3 番目の部分の電子メール アドレスを取得する必要があります。3 番目の部分は、ユーザーがそのゲームのスコアを既に持っているかどうか、新しいスコアの方が高いかどうかを確認することです。

リーリー

コードは正常に動作しているように見えますが、非常に遅いです。また、数千レコード後にスクリプトがタイムアウトするか、何かが発生するようです。この仕事を行うもっと良い方法はありますか?

Python で再コーディングしてみましたが、さらに遅くなり、データベースに行が挿入されないようでした。私は Python をほとんど知らないので、おそらく役に立ちません。

配列を作成して挿入する必要がある項目を保存し、一度に 100 行などを挿入することを考えていましたが、スコア結合テーブルの ID を取得する必要があります。また、データベースで UNIQUE 制約を使用することも検討しており、電子メール アドレスやゲームの重複を防ぐために挿入コードを書き換える方法を見つけようとしています。

P粉423694341P粉423694341313日前471

全員に返信(2)返信します

  • P粉442576165

    P粉4425761652024-01-17 19:06:56

    ここにはまだ改善の余地がたくさんあります。データベースの速度に関して言えば、通常、主な目標はデータベース サーバーへのヒット数を減らすことです。

    まず、各 CSV 行に対して電子メールから ID へのクエリを実行しますが、これは必須ではありません。多くてもユーザーごとに 1 回実行し、キャッシュする必要があります。さらに良いことに、コレクション全体に対してこれを 1 回実行して、内容全体をメモリ配列に読み取ることができます。このようなもの: ### リーリー

    これにより、次のような配列が得られます:

    リーリー

    これをスクリプトの先頭で 1 回実行し、全体を通じてメモリに保持します。これにより、特定のメールの ID を即座に見つけることができます。これにより、データベースから 7999 回のクリックが削除されます。基本的に、CPU とディスク時間とメモリを交換することになります。配列にまだ存在しない電子メールを見つけた場合は、それを挿入して配列に追加できます。

    次に、準備をループ反復の外側に移動します。これにより、少なくとも 3 * 7999 のクリックがデータベースから削除され、場合によっては最大 5 * 7999 のクリックが削除されます。

    次に、explode() の代わりに fgetcsv() を使用します。これは、より簡単で参照を正しく処理できるためです。単一の挿入を実行する前に CSV 全体を処理します。ほとんどのレコードを破棄するだけの場合、これほど大量のデータベース トラフィックを作成するのは愚かです。したがって、最初に最大値を計算し、次にこれらのみを使用してデータベースにアクセスします。

    リーリー

    指定された入力ファイル:

    リーリー

    これにより、各ユーザーの最高スコアの配列が生成されます:

    リーリー

    その後、配列を反復処理し、それらのレコードのみに基づいて挿入/更新を実行できます。これにより、冗長な CSV 行ごとに 2 つのクエリが保存されます。

    リーリー

    返事
    0
  • P粉860897943

    P粉8608979432024-01-17 11:01:02

    e メール、game_id、および Score パラメーターを使用してストアド プロシージャを作成します。すべての SQL 作業をプロセスに実行させます。 PHP コードは、プロシージャを呼び出す単一のループに縮小されます。結果はより速く、より簡単に保守できるはずです:

    リーリー

    ループが依然として遅すぎる場合は、速度低下の他の理由がある可能性があります。

    返事
    0
  • キャンセル返事