我有一個簡單的MySQL 5.6.23 GROUP BY查詢,它需要32秒才能在RDS db.r3.xlarge instance上運行。 InnoDB表格大約有47M行。 explain
說我選擇了大約8K。最終的GROUP BY輸出有86行。根據show processlist;
99%的時間花在Creating sort index
上。如果我大大增加menu_id in (...)
列表中的ids數量,查詢需要10-30分鐘。優化困在「創建排序索引」的簡單MySQL GROUP BY查詢
不幸的是,我無法從數據庫服務器複製/粘貼文本到這個終端,所以下面的表格輸出是縮寫的。
查詢信息:
SELECT COUNT(DISTINCT user_id) AS count_user_id, org, category
FROM menu_views
WHERE menu_id in (
...about 1300 ids...
) GROUP BY org, category;
explain;
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 | SIMPLE | menu_views | range | i_menu_view_menu_id,tyler_group,tyler_user_group,tyler_user_menu_group,tyler_menu_group | i_menu_views_menu_id | 5 | NULL | 7914 | Using index condition; Using filesort |
輸出:
| count_user_id | org | category |
|--------------------------------|
| 13000 | foo | pizza |
| 1 | bar | candy |
| 90 | baz | cheese |
| 80 | gaz | soda |
| 150 | urk | pizza |
| ... etc (86 rows) ... |
|--------------------------------|
背景信息:
describe menu_views;
| Field | Type | Null | Key | Default |
|------------------------------------------------|
| id | int(11) | NO | PRI | NULL |
| menu_id | int(11) | YES | MUL | NULL |
| user_id | int(11) | YES | MUL | NULL |
| category | varchar(255) | NO | | UNKNOWN |
| org | varchar(255) | NO | MUL | UNKNOWN |
|------------------------------------------------|
show index from menu_views;
| Key_name | Seq_in_index | Column_name |
|-----------------------------------------------------|
| PRIMARY | 1 | id |
| i_menu_views_menu_id | 1 | menu_id |
| tyler_group | 1 | org |
| tyler_group | 2 | category |
| tyler_user_group | 1 | user_id |
| tyler_user_group | 2 | org |
| tyler_user_group | 3 | category |
| tyler_user_menu_group | 1 | user_id |
| tyler_user_menu_group | 2 | menu_id |
| tyler_user_menu_group | 3 | org |
| tyler_user_menu_group | 4 | category |
| tyler_menu_group | 1 | menu_id |
| tyler_menu_group | 2 | org |
| tyler_menu_group | 3 | category |
|-----------------------------------------------------|
有AR e表中的其他索引,但這些是通過EXPLAIN
顯示的索引。我添加了tyler_*
,試圖強制使用loose index scan,但沒有幫助。
org
和category
字段正確屬於users
,但我非規範化它們,希望非JOIN查詢會更快。但是,我沒有看到任何性能改進。
完全披露:我使用此查詢的幾個變體,所有這些變化都很慢。這是最簡單的變體。其他包括WHERE created_at BETWEEN ('X' and 'Y')
和GROUP BY year/month/week/day(created_at), category
。