4

SELECT foo, bar, FROM users1 つのクエリで 500 行を返す場合と、500 のSELECT foo, bar, FROM users WHERE id = xクエリを一度に返す場合とで、パフォーマンスにかなりの違いはありますか?

私が書いている PHP アプリケーションでは、約 500 の SELECT ステートメントを生成する明確で読みやすいコード セクションのどちらかを選択しようとしています。または、500 行を返す SELECT を 1 つだけ使用する、あいまいで複雑な方法で it を記述します。

私は明確で保守しやすいコードを使用する方法を好みますが、各 SELECT の接続オーバーヘッドがパフォーマンスの問題を引き起こすことを懸念しています。

関連する場合の背景情報: 1) これは、PHP でコーディングされた Drupal モジュールです 2) 問題のテーブルは、INSERT と UPDATE をほとんど取得せず、めったにロックされません質問

ありがとう!

4

3 に答える 3

9

ほとんどの場合、1 つの行に対して大量の SELECT を実行するよりも、1 つの大きなバッチ SELECT を実行して結果をアプリケーション コードで解析する方が高速です。ただし、両方を実装してプロファイルすることをお勧めします。必要な仮定の数を最小限に抑えるよう常に努力してください。

于 2009-12-05T17:05:28.443 に答える
3

特にすべてのクエリ間の接続を閉じていない場合は、mysql クエリの接続オーバーヘッドについてあまり心配しません。クエリが一時テーブルを作成する場合、クエリのオーバーヘッドよりも多くの時間をクエリに費やしていることを考慮してください。

個人的には複雑な SQL クエリを実行するのが大好きですが、テーブルのサイズ、mysql クエリ キャッシュ、および範囲チェック (インデックスに対しても) を実行する必要があるクエリのクエリ パフォーマンスのすべてが違いを生むことがわかりました。

私はこれを提案します:

1)シンプルで正しいベースラインを確立します。これは無数のクエリのアプローチだと思います。これは間違いではなく、非常に正しい可能性が非常に高いです。数回実行して、クエリ キャッシュとアプリケーションのパフォーマンスを確認します。特に他のコード メンテナーと協力している場合は、アプリをメンテナンスしやすい状態に保つことが非常に重要です。また、非常に大きなテーブルをクエリしている場合は、小さなクエリでスケーラビリティが維持されます。

2)複雑なクエリをコーディングします。結果の精度を比較してから、時間を比較します。次に、クエリで EXPECT を使用して、スキャンされた行が何であるかを確認します。JOIN、WHERE x != y、または一時テーブルを作成する条件がある場合、特に常に更新されるテーブルにいる場合、クエリのパフォーマンスがかなり悪くなることがよくあります。ただし、複雑なクエリは正しくない可能性があり、複雑なクエリはアプリケーションが大きくなるにつれて壊れやすくなることもわかりました。複雑なクエリは通常、より大きな行セットをスキャンし、多くの場合、一時テーブルを作成してusing whereスキャンを呼び出します。テーブルが大きくなればなるほど、これらはより高価になります。また、複雑なクエリがチームの強みに合わないというチームの考慮事項がある場合もあります。

3) 結果をチームと共有します。

複雑なクエリは mysql クエリ キャッシュにヒットする可能性が低く、十分に大きい場合はキャッシュしないでください。(頻繁にヒットするクエリのために mysql クエリ キャッシュを保存する必要があります。) また、インデックスをスキャンする必要がある述語を含むクエリもうまくいきません。(x != y、x > y、x < y)。のようなクエリは、SELECT foo, bar FROM users WHERE foo != 'g' and mumble < '360'最終的にスキャンを実行します。(その場合、クエリのオーバーヘッドのコストは無視できます。)

小規模なクエリは、選択して述語しているフィールドがインデックス化されている限り、インデックスからすべての値を取得するだけで一時テーブルを作成せずに完了することがよくあります。そのため、 のクエリ パフォーマンスSELECT foo, bar FROM users WHERE id = xは非常に優れています (特に、列foobarが のようにインデックス付けされている場合alter table users add index ix_a ( foo, bar );)。

アプリケーションのパフォーマンスを向上させるその他の良い方法は、これらの小さなクエリ結果をアプリケーションにキャッシュする (適切な場合) か、マテリアライズド ビュー クエリのバッチ ジョブを実行することです。また、memcached または XCache にあるいくつかの機能を検討してください。

于 2009-12-06T07:33:26.660 に答える
1

500 のid値が何であるかを知っているように見えるので、次のようにしてみませんか。

// Assuming you have already validated that this array contains only integers
// so there is not risk of SQl injection

$ids = join(',' $arrayOfIds);

$sql = "SELECT `foo`, `bar` FROM `users` WHERE `id` IN ($ids)";
于 2009-12-05T17:13:10.787 に答える