2011-02-08 18 views
1
UPDATE users u 
JOIN (select count(*) as job_count, user_id from job_responses where date_created > subdate(now(), 30) group by user_id) j 
ON j.user_id = u.user_id 
JOIN users_profile p 
ON p.user_id = u.user_id 
JOIN users_roles_xref x 
ON x.user_id = u.user_id 
SET num_job_responses = least(j.job_count, 5) 
WHERE u.status = 1 AND p.visible = "Y" AND x.role_id = 2000 

に参加し、説明することは私に告げるこの:MySQLが最適化サブセレクト

+----+-------------+---------------+--------+---------------------------------+---------------+---------+----------------------+--------+----------------------------------------------+ 
| id | select_type | table   | type | possible_keys     | key   | key_len | ref     | rows | Extra          | 
+----+-------------+---------------+--------+---------------------------------+---------------+---------+----------------------+--------+----------------------------------------------+ 
| 1 | PRIMARY  | <derived2> | ALL | NULL       | NULL   | NULL | NULL     | 23008 |            | 
| 1 | PRIMARY  | u    | eq_ref | PRIMARY,user_id,status,status_2 | PRIMARY  | 4  | j.user_id   |  1 | Using where         | 
| 1 | PRIMARY  | p    | ref | user_id,visible     | user_id  | 4  | scoop_jazz.u.user_id |  2 | Using where         | 
| 1 | PRIMARY  | x    | ref | index_role_id,index_user_id  | index_user_id | 4  | scoop_jazz.u.user_id |  3 | Using where         | 
| 2 | DERIVED  | job_responses | range | date_created     | date_created | 4  | NULL     | 135417 | Using where; Using temporary; Using filesort | 
+----+-------------+---------------+--------+---------------------------------+---------------+---------+----------------------+--------+----------------------------------------------+ 

私はトラブルを説明して、このクエリの最適化を抱えています。それを行う方法は?

答えて

0

一時テーブルを生成し、それを作成してから、そのテーブルに対して結合を使用する方が簡単で高速になりました。私は元のクエリを「チャンク」していました。サブクエリによって作成されたテーブルを作成して破棄する必要がある場合、非常に高価になります。

1

job_responses(date_created、user_id)にインデックスを追加すると便利です。 次に、現在の単一列インデックスをdate_createdにドロップできます。

クエリの最も高価な部分は、サブクエリ

(select count(*) as job_count, user_id 
from job_responses 
where date_created > subdate(now(), 30) 
group by user_id) 

ノートの2つのフィールドのみがUSER_IDとDATE_CREATEDされています。 date_created in last 30 daysを満たすように選択されたdate_createdにインデックスがあります。ただし、データページに戻ってuser_idを取得し、それをグループ化する必要があります。

複合インデックスがある場合、user_idはインデックスから直接利用できます。また、単一列の索引date_createdも対象です。そのため、その列を削除できます。

+0

なぜか説明してください。 – Ikke

+0

実際にそのインデックスを選択しましたが、説明とクエリの時間は基本的に変わりません。 – zombor