Mysql查询优化 - 范围搜索

时间:2013-09-12 11:45:15

标签: mysql sql optimization query-optimization

希望找到有关如何优化此查询的一些想法 - 使用多个范围搜索非常尴尬

SELECT t1.id, t1.custom_track_id, t1.deleted, t1.last_modified, t1.client_id
FROM tracks t1
INNER JOIN tracks t2 ON t1.custom_track_id = t2.custom_track_id
AND t1.last_modified > t2.last_modified
AND t1.deleted !=0
AND t2.deleted =0
AND t2.client_id
IN ( 103, 115, 116 ) 
WHERE t1.client_id
IN ( 103, 115, 116 ) 

它寻找和加入的所有字段都是INT字段。

索引(是的,那里有几个狡猾的索引):

+--------+------------+------------------------------------------------+--------------+----------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name                                       | Seq_in_index | Column_name                | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+------------------------------------------------+--------------+----------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tracks |          0 | PRIMARY                                        |            1 | id                         | A         |      566045 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | client_id                                      |            1 | client_id                  | A         |         589 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | featured                                       |            1 | featured                   | A         |          16 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | system_status                                  |            1 | system_status              | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | created_by                                     |            1 | created_by                 | A         |         225 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | custom_track_id                                |            1 | custom_track_id            | A         |      283022 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | custom_track_id                                |            2 | custom_artist_id           | A         |      283022 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | counterpoint_id                                |            1 | counterpoint_id            | A         |      113209 |     NULL | NULL   | YES  | BTREE      |         |               |
| tracks |          1 | system_status_2                                |            1 | system_status              | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | composition                                    |            1 | composition                | A         |          13 |     NULL | NULL   | YES  | BTREE      |         |               |
| tracks |          1 | published_start_date                           |            1 | published_start_date       | A         |          13 |     NULL | NULL   | YES  | BTREE      |         |               |
| tracks |          1 | published_end_date                             |            1 | published_end_date         | A         |          13 |     NULL | NULL   | YES  | BTREE      |         |               |
| tracks |          1 | deleted                                        |            1 | deleted                    | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | restricted_access_required                     |            1 | restricted_access_required | A         |          13 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | mv_clientid_deleted_featured_restrictedaccess  |            1 | client_id                  | A         |         336 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | mv_clientid_deleted_featured_restrictedaccess  |            2 | custom_track_id            | A         |         336 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | mv_clientid_deleted_featured_restrictedaccess  |            3 | deleted                    | A         |         336 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | mv_clientid_deleted_featured_restrictedaccess  |            4 | last_modified              | A         |         336 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | mv_clientid_customtrackid_deleted_lastmodified |            1 | client_id                  | A         |         336 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | mv_clientid_customtrackid_deleted_lastmodified |            2 | custom_track_id            | A         |         336 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | mv_clientid_customtrackid_deleted_lastmodified |            3 | deleted                    | A         |         336 |     NULL | NULL   |      | BTREE      |         |               |
| tracks |          1 | mv_clientid_customtrackid_deleted_lastmodified |            4 | last_modified              | A         |         336 |     NULL | NULL   |      | BTREE      |         |               |
+--------+------------+------------------------------------------------+--------------+----------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

和EXPLAIN:

---+---------+-------------------------------------------------+-------+--------------------------+
| id | select_type | table | type  | possible_keys                                                                                                                  | key                                           | key_len | ref                                             | rows  | Extra                    |
+----+-------------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+---------+-------------------------------------------------+-------+--------------------------+
|  1 | SIMPLE      | t1    | range | client_id,custom_track_id,deleted,mv_clientid_deleted_featured_restrictedaccess,mv_clientid_customtrackid_deleted_lastmodified | mv_clientid_deleted_featured_restrictedaccess | 4       | NULL                                            | 16018 | Using where; Using index |
|  1 | SIMPLE      | t2    | ref   | client_id,custom_track_id,deleted,mv_clientid_deleted_featured_restrictedaccess,mv_clientid_customtrackid_deleted_lastmodified | custom_track_id                               | 302     | synchtank_shared_application.t1.custom_track_id |     2 | Using where              |
+----+-------------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+---------+-------------------------------------------------+-------+--------------------------+

所以寻找优化查询或索引的方法。我也很好奇为什么它可以匹配2个复合索引,它选择没有last_modified的那个。

斯蒂芬的解释:

+----+-------------+-------+-------+-----------------------------------------------+-----------------------------------------------+---------+------+-------+---------------------------------------------+
| id | select_type | table | type  | possible_keys                                 | key                                           | key_len | ref  | rows  | Extra                                       |
+----+-------------+-------+-------+-----------------------------------------------+-----------------------------------------------+---------+------+-------+---------------------------------------------+
|  1 | SIMPLE      | t1    | range | client_id                                     | client_id                                     | 4       | NULL |  8111 | Using where                                 |
|  1 | SIMPLE      | t2    | range | mv_clientid_deleted_featured_restrictedaccess | mv_clientid_deleted_featured_restrictedaccess | 4       | NULL | 16018 | Using where; Using index; Using join buffer |
+----+-------------+-------+-------+-----------------------------------------------+-----------------------------------------------+---------+------+-------+---------------------------------------------+

1 个答案:

答案 0 :(得分:0)

您可以尝试强制mysql使用索引:

SELECT 
    t1.id, 
    t1.custom_track_id, 
    t1.deleted, 
    t1.last_modified, 
    t1.client_id
FROM 
    tracks t1 FORCE INDEX(`client_id`)
INNER JOIN tracks t2 FORCE INDEX(`mv_clientid_deleted_featured_restrictedaccess`)
    ON t1.custom_track_id = t2.custom_track_id
    AND t1.last_modified > t2.last_modified 
    AND t2.deleted = 0
    AND t2.client_id IN ( 103, 115, 116 ) 
WHERE 
    t1.client_id IN ( 103, 115, 116 ) 
    AND t1.deleted !=0

通常,mysql不使用最有效索引的原因是由于基数中的虚假统计数据,这就是为什么在具有大量列和索引的大表上运行OPTIMIZE TABLE的好习惯。