そこで私は、リーグ内のピンボール マシンのハイスコアを追跡するための小さなデータベースを構築しようとしています。 AI ID 列と電子メール アドレスを含む列のみを持つユーザーのテーブルがあります。次に、AI ID 列とマシンの名前であるゲーム テーブルがあります。これは多対多の関係であるため、user_id、game_id、および Score を列として含む「scores」という 3 番目のテーブルを作成しました。
編集: 読み取りコードを含めます:
リーリー同様のコードを使用して、ゲームがデータベースにすでにリストされているかどうかを確認します。ゲームの ID 番号と 3 番目の部分の電子メール アドレスを取得する必要があります。3 番目の部分は、ユーザーがそのゲームのスコアを既に持っているかどうか、新しいスコアの方が高いかどうかを確認することです。
リーリーコードは正常に動作しているように見えますが、非常に遅いです。また、数千レコード後にスクリプトがタイムアウトするか、何かが発生するようです。この仕事を行うもっと良い方法はありますか?
Python で再コーディングしてみましたが、さらに遅くなり、データベースに行が挿入されないようでした。私は Python をほとんど知らないので、おそらく役に立ちません。
配列を作成して挿入する必要がある項目を保存し、一度に 100 行などを挿入することを考えていましたが、スコア結合テーブルの ID を取得する必要があります。また、データベースで UNIQUE 制約を使用することも検討しており、電子メール アドレスやゲームの重複を防ぐために挿入コードを書き換える方法を見つけようとしています。
P粉4425761652024-01-17 19:06:56
ここにはまだ改善の余地がたくさんあります。データベースの速度に関して言えば、通常、主な目標はデータベース サーバーへのヒット数を減らすことです。
まず、各 CSV 行に対して電子メールから ID へのクエリを実行しますが、これは必須ではありません。多くてもユーザーごとに 1 回実行し、キャッシュする必要があります。さらに良いことに、コレクション全体に対してこれを 1 回実行して、内容全体をメモリ配列に読み取ることができます。このようなもの: ### リーリー
これにより、次のような配列が得られます:リーリー
これをスクリプトの先頭で 1 回実行し、全体を通じてメモリに保持します。これにより、特定のメールの ID を即座に見つけることができます。これにより、データベースから 7999 回のクリックが削除されます。基本的に、CPU とディスク時間とメモリを交換することになります。配列にまだ存在しない電子メールを見つけた場合は、それを挿入して配列に追加できます。次に、準備をループ反復の外側に移動します。これにより、少なくとも 3 * 7999 のクリックがデータベースから削除され、場合によっては最大 5 * 7999 のクリックが削除されます。
次に、explode() の代わりに fgetcsv() を使用します。これは、より簡単で参照を正しく処理できるためです。単一の挿入を実行する前に CSV 全体を処理します。ほとんどのレコードを破棄するだけの場合、これほど大量のデータベース トラフィックを作成するのは愚かです。したがって、最初に最大値を計算し、次にこれらのみを使用してデータベースにアクセスします。
リーリー
指定された入力ファイル:リーリー
これにより、各ユーザーの最高スコアの配列が生成されます:リーリー
その後、配列を反復処理し、それらのレコードのみに基づいて挿入/更新を実行できます。これにより、冗長な CSV 行ごとに 2 つのクエリが保存されます。リーリー
P粉8608979432024-01-17 11:01:02
e メール、game_id、および Score パラメーターを使用してストアド プロシージャを作成します。すべての SQL 作業をプロセスに実行させます。 PHP コードは、プロシージャを呼び出す単一のループに縮小されます。結果はより速く、より簡単に保守できるはずです:
リーリーループが依然として遅すぎる場合は、速度低下の他の理由がある可能性があります。