2011-02-08 135 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) 

只有兩個值得注意的領域是USER_ID和DATE_CREATED。在date_created上有一個索引,選擇該索引以滿足date_created in last 30 days。但是,它將不得不返回到數據頁面以檢索user_id,然後進行分組。

如果您有組合索引,則可以直接從索引獲取user_id。它還涵蓋了單列索引date_created,因此您可以放棄該列索引。

+0

小心解釋爲什麼? – Ikke 2011-02-08 20:07:10