【发布时间】:2017-06-10 21:23:31
【问题描述】:
我正在调试一个耗时太多的 MYSQL 查询。
查询是这样的:
SELECT *, TM.tutor_id as tutor_id,
TIMESTAMPDIFF( YEAR, birthdate, CURDATE( ) ) AS age
FROM tutor_master as TM
LEFT JOIN category_master as CM on CM.category_id=TM.category
LEFT JOIN tutor_expected_rate TER ON FIND_IN_SET(TER.tutor_id, TM.tutor_id) > 0
LEFT JOIN admin_shortlist_master SHM ON TM.tutor_id = SHM.tutor_id
AND (SHM.user_auth_id = 'c84258e9c39059a89ab77d846ddab909')
LEFT JOIN level_master LM ON FIND_IN_SET(LM.level_id, TER.level_id) > 0
WHERE 1=1
GROUP BY TM.tutor_id
order by TM.is_priority DESC, TM.tutor_id DESC LIMIT 0, 10
如果我排除部分
WHERE 1=1
GROUP BY TM.tutor_id
ORDER BY TM.is_priority DESC, TM.tutor_id DESC LIMIT 0, 10
查询是这样执行的:
显示第 0 - 29 行(总共 27,649 行,查询耗时 0.2339 秒)
对于完整查询,它是这样的:
显示第 0 - 9 行(共 10 行,查询耗时 115.4066 秒)
我已经为查询中使用的所有字段编制了索引。
MYSQL的解释是这样的:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE TM ALL NULL NULL NULL NULL 27530 Using temporary; Using filesort
1 SIMPLE CM eq_ref PRIMARY PRIMARY 4 toprecru_portal_db.TM.category 1
1 SIMPLE TER ALL NULL NULL NULL NULL 13223
1 SIMPLE SHM ref tutor_id,user_auth_id user_auth_id 257 const 1
1 SIMPLE LM ALL NULL NULL NULL NULL 11
更新:
我在某处读到使用 1=1 不会对性能产生影响,但即使添加 1=1,查询也需要从 0.2339 秒到大约 70 秒。
MYSQL my.cnf 设置如下:
read_buffer_size = 512M
join_buffer_size = 512M
sort_buffer_size = 256M
更新:
当使用 group_by 而没有 order_by 时,时间几乎是一样的:
显示第 0 - 29 行(总共 27,530 行,查询耗时 114.9642 秒)
更新样本日期: 表 - 导师期望率
id tutor_id level_id exp_rate
1 27597 4 $30-35/hr
2 27597 10 $40-45/hr
99 27598 5 35-40/hr minimum
124 27602 4 25-30/hr or 30-40/hr minimum 1.5hrs per session
125 27602 0
表格 - admin_shortlist_master
admin_shortlist_id job_ad_id request_profile_id tutor_id user_auth_id added_date
143693 0 0 22692 4ef44ea2203114a3e27eaff31a1bf3be 2015-09-17
143694 0 0 11653 4ef44ea2203114a3e27eaff31a1bf3be 2015-09-17
143695 0 0 27611 4ef44ea2203114a3e27eaff31a1bf3be 2015-09-17
143696 0 0 27610 4ef44ea2203114a3e27eaff31a1bf3be 2015-09-17
296793 0 13 0 21232f297a57a5a743894a0e4a801fc3 2015-10-05
table-category master
category_id category_name disp_order status 0-Not Published, 1-Published
1 Polytechnic Student 0 1
2 Diploma Grad Part Time 1 1
3 Diploma Grad Full Time 2 1
4 JC Student 3 0
5 A Level Grad Part Time 4 1
表级主控
level_id level_name class_title class_ids subject_ids status 0-Not Published, 1-Published
4 Primary Primary 4,5,6,7,8,9,10 5,6,7,8,9,10,11,12,14,15 1
5 O Level (Secondary) Secondary 12,13,14,15,16
4,5,6,7,8,9,10,13,14,15,16,17,18,19,20,21,22,23,24... 1
6 A Level (JC) JC 18,19,20 6,17,18,19,23,24,25,26,30,31,32,33,34,35,36,37,38,... 1
7 International Baccalaureate 17,18,19,23,24,34,40,41,42,43,44,45,46,47,48,49,50... 1
8 Diploma 26,34,47,54,55,56,57,59,60,61,62,63,64,65,66,67,68... 1
更新:
select tutor_id, category, is_priority, birthdate from tutor_master order by tutor_id limit 5
tutor_id Ascending 1 category is_priority birthdate
4 8 0 1989-01-01
7 8 0 1987-01-01
8 8 0 1964-01-01
9 2 0 1987-01-01
10 8 0 1983-01-01
【问题讨论】:
-
@Bamar - 实际上我正在调试别人的查询。我想知道为什么要这样使用它,因为在那些列中没有逗号分隔的值。但是话虽如此,即使我不使用 where、group by 和 order by 时使用它,速度也相当不错。
-
这就是我删除评论的原因,我之前没有看到问题的那部分。
-
如果你只使用
GROUP BY而不使用ORDER BY会发生什么? -
@Barmar - 更新您的查询问题。
-
@Pawan 我也想知道你为什么使用
GROUP BY,因为你没有像SUM()或COUNT()这样的聚合函数。