php - MYSQL 查询在使用 where、group by 和 order by 时花费太多时间

标签 php mysql

我正在调试一个耗时过多的 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

查询是这样执行的:

Showing rows 0 - 29 ( 27,649 total, Query took 0.2339 sec)

完整查询是这样的:

Showing rows 0 - 9 ( 10 total, Query took 115.4066 sec)

我已经为查询中使用的所有字段编制了索引。

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

更新:

在不使用 order_by 的情况下使用 group_by 时,时间几乎相同:

Showing rows 0 - 29 ( 27,530 total, Query took 114.9642 sec)

更新样本日期: 表 - 导师期望率

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  

表格-类别大师

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

最佳答案

在不知道表结构和一些样本数据的情况下调试起来有点困难(如果您可以编辑原始问题以包含这些数据会有所帮助)。看来您最大的问题是所有表上都没有标记。

您应该能够得到这样的输出,其中所有内容都使用索引:

+------+-------------+-------+--------+---------------+----------+---------+--------------------------+------+--------------------------------------------------------------+
| id   | select_type | table | type   | possible_keys | key      | key_len | ref                      | rows | Extra                                                        |
+------+-------------+-------+--------+---------------+----------+---------+--------------------------+------+--------------------------------------------------------------+
|    1 | SIMPLE      | TM    | ALL    | NULL          | NULL     | NULL    | NULL                     |    2 | Using temporary; Using filesort                              |
|    1 | SIMPLE      | CM    | eq_ref | PRIMARY       | PRIMARY  | 4       | tutors.TM.category       |    1 | Using index                                                  |
|    1 | SIMPLE      | TER   | index  | NULL          | tutor_id | 8       | NULL                     |    1 | Using where; Using index; Using join buffer (flat, BNL join) |
|    1 | SIMPLE      | SHM   | eq_ref | tutor_id      | tutor_id | 606     | tutors.TM.tutor_id,const |    1 | Using where; Using index                                     |
|    1 | SIMPLE      | LM    | index  | NULL          | PRIMARY  | 4       | NULL                     |    1 | Using where; Using index; Using join buffer (flat, BNL join) |
+------+-------------+-------+--------+---------------+----------+---------+--------------------------+------+--------------------------------------------------------------+

因为您正在使用 FIND_IN_SET,您可能无法删除连接缓冲区,而且它似乎总是需要对导师进行全表扫描,这应该不是问题。

这些是我对所有表格的标记:

MariaDB [tutors]> show indexes from admin_shortlist_master;
+------------------------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table                  | Non_unique | Key_name | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------------------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| admin_shortlist_master |          0 | PRIMARY  |            1 | id           | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| admin_shortlist_master |          0 | tutor_id |            1 | tutor_id     | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| admin_shortlist_master |          0 | tutor_id |            2 | user_auth_id | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+------------------------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)

MariaDB [tutors]> show indexes from category_master;
+-----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table           | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| category_master |          0 | PRIMARY  |            1 | category_id | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

MariaDB [tutors]> show indexes from level_master;
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table        | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| level_master |          0 | PRIMARY  |            1 | level_id    | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

MariaDB [tutors]> show indexes from tutor_expected_rate;
+---------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table               | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tutor_expected_rate |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| tutor_expected_rate |          0 | tutor_id |            1 | tutor_id    | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| tutor_expected_rate |          0 | tutor_id |            2 | level_id    | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+---------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)

如果您想提供您的整体结构和一些样本数据,那么可能还有一种方法可以索引 tutor_master 表,但目前很难确定。

关于php - MYSQL 查询在使用 where、group by 和 order by 时花费太多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44478211/

相关文章:

mysql - 我想结合两个nodejs程序以获得一个结果: specific CSV data filtered by type - how do I combine the code properly?

mysql - JPA在具有不同列名的复合键之间一对多映射

javascript - 提交后无法取消禁用已从数据库获取其值的复选框

php - 如何按范围形成选择查询

php - 如何为使用 laravel 表单构建器创建的选择标签的选项指定 HTML 属性?

mysql - 如果一个或另一个或两个字段匹配,则获取行

mysql - 这是加入的工作吗

php - jquery向多个选择下拉列表添加属性

php - 如何使用 Angular 显示 PHP MySQL 查询的输出

php - 为什么我应该在 Laravel 中同时使用特征和服务?