1

私は2つのテーブルを持っています:

poll_response (poll_id, option_id, user_id) (約 500,000 行、500 の一意のポーリング、1000 の一意のオプション、および 25000 の一意のユーザー)

preferred_users (user_id) (約800行)

各オプションを選択したユーザーの何パーセントが「優先ユーザー」(つまり、評判の高いユーザー) であるかを判断したいと思います。他のユーザーは投票に応答できます。応答が優先ユーザーからのものであることを識別するために、preferred_users テーブルへの結合が必要です。

これが私が持っているものです:

SELECT option_id, count(*) AS all_votes, count(preferred_users.user_id) AS preferred_votes
FROM response
LEFT JOIN preferred_users ON response.user_id = preferred_users.user_id
GROUP BY option_id

クエリは、次のようなテーブルを吐き出します。

| option_id | all_votes | preferred_votes
| 1         | 500       | 150
| 2         | 550       | 250
| 3         | 525       | 300

次に、計算を行ってパーセンテージを決定します。

問題は、クエリが頻繁にタイムアウトになることです。つまり、完了するまでに 1 分以上かかるということです。

左結合を取り除くか、クエリを最適化する方法はありますか?

4

1 に答える 1

1

合計と優先ユーザーの2つのクエリに分割してみましたか?動作が遅くなる原因は、null以外のエントリをカウントするグループ内のエントリを実行していることだと思います(ただし、explainを使用すると自分自身を確認できます)。

言い換えると:

select option_id, count(*) from response group by option_id
select option_id, count(*) from response, preferred_users where response.user_id = preferred_user.id group by option_id

あなたもそれらに参加することができます:

select * from 
  (select option_id, count(*) as total from response group by option_id
   left join
   select option_id, count(*) as preferred from response, preferred_users where response.user_id = preferred_user.id group by option_id
   using (option_id))

(私がそこに構文を持っているかどうかはわかりませんが、あなたは考えを理解します)。

また、preferred_users.id列にもインデックスがありますよね?そして、一方から他方への外部キー関係?そうでない場合は、最初にそれを試してください。

于 2012-02-27T20:28:38.257 に答える