MySQL不同的解释计划为同一个查询

时间:2015-10-22 15:11:33

标签: mysql optimization explain

我有以下在本地执行良好的查询(0.4执行时间是可以接受的):

SELECT categories.*, parameters_values.key, l.* FROM categories
JOIN parameters_values ON parameters_values.parameter_id = 2 AND parameters_values.country_id = 223
JOIN categories_countries ON categories.category_id = categories_countries.category_id AND categories_countries.country_id = 223
JOIN listings AS l ON l.listing_id = (
    SELECT listings.listing_id FROM listings
    JOIN listings_categories ON listings.listing_id = listings_categories.listing_id
    JOIN categories AS c ON listings_categories.category_id = c.category_id
    WHERE
    (c.category_id = categories.category_id OR c.subcategory = categories.category_id) AND
    CASE parameters_values.`key`
        WHEN 1 THEN listings.transaction_type = 1 OR listings.transaction_type = 3
        WHEN 2 THEN listings.transaction_type = 2 OR listings.transaction_type = 3
        WHEN 3 THEN true
    END AND
    listings.country_id = 223 AND
    listings.property_type = 1 AND
    listings.active = 1 AND
    listings.published_flag = 1 AND
    st_intersects(
    POINT(listings.lng, listings.lat),
    (SELECT IFNULL(`l`.`polygon`, GET_SQUARE(`l`.`lat`, `l`.`lng`, `l`.`radius`, `l`.`country_id`)) 
    FROM `locations` AS `l` WHERE `location_id` = 1 LIMIT 1)
    )

    LIMIT 1
) ORDER BY categories.subcategory, categories.`order`

它只是检查一个类别中列表的存在,那里有一个位置搜索,没有什么过于复杂。本地执行计划如下:

+----+--------------------+----------------------+--------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+------------------------------------------------+
| id | select_type        | table                | type   | possible_keys                                                                                                                          | key                                     | key_len | ref                                 | rows | Extra                                          |
+----+--------------------+----------------------+--------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+------------------------------------------------+
|  1 | PRIMARY            | parameters_values    | ref    | parameter_id,country_id                                                                                                                | parameter_id                            | 8       | const,const                         |    3 | Using temporary; Using filesort                |
|  1 | PRIMARY            | categories_countries | ref    | PRIMARY,categories_countries_country_id_foreign                                                                                        | categories_countries_country_id_foreign | 4       | const                               |  122 | Using index                                    |
|  1 | PRIMARY            | categories           | eq_ref | PRIMARY                                                                                                                                | PRIMARY                                 | 4       | cp.categories_countries.category_id |    1 | NULL                                           |
|  1 | PRIMARY            | l                    | eq_ref | PRIMARY,listings_listing_id_transaction_type                                                                                           | PRIMARY                                 | 4       | func                                |    1 | Using where                                    |
|  2 | DEPENDENT SUBQUERY | c                    | ALL    | PRIMARY,categories_subcategory_foreign                                                                                                 | NULL                                    | NULL    | NULL                                |  127 | Range checked for each record (index map: 0x5) |
|  2 | DEPENDENT SUBQUERY | listings_categories  | ref    | PRIMARY,listings_categories_category_id_foreign                                                                                        | listings_categories_category_id_foreign | 4       | cp.c.category_id                    |  273 | Using index                                    |
|  2 | DEPENDENT SUBQUERY | listings             | eq_ref | PRIMARY,listings_country_id_foreign,listings_country_created_at,listings_country_units_created_at,listings_listing_id_transaction_type | PRIMARY                                 | 4       | cp.listings_categories.listing_id   |    1 | Using where                                    |
|  3 | SUBQUERY           | l                    | const  | PRIMARY                                                                                                                                | PRIMARY                                 | 4       | const                               |    1 | NULL                                           |
+----+--------------------+----------------------+--------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+------------------------------------------------+

但是,查询似乎在服务器上的执行方式不同,因为后四行是:

|  2 | DEPENDENT SUBQUERY | listings             | ref    | PRIMARY,listings_country_id_foreign,listings_country_created_at,listings_country_units_created_at,listings_listing_id_transaction_type | listings_country_id_foreign             | 4       | const                               | 18238 | Using where                     |
|  2 | DEPENDENT SUBQUERY | listings_categories  | ref    | PRIMARY,listings_categories_category_id_foreign                                                                                        | PRIMARY                                 | 4       | cp.listings.listing_id              |     1 | Using index                     |
|  2 | DEPENDENT SUBQUERY | c                    | eq_ref | PRIMARY,categories_subcategory_foreign                                                                                                 | PRIMARY                                 | 4       | cp.listings_categories.category_id  |     1 | Using where                     |
|  3 | SUBQUERY           | l                    | const  | PRIMARY                                                                                                                                | PRIMARY                                 | 4       | const                               |     1 | NULL                            |
+----+--------------------+----------------------+--------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+-------+---------------------------------+

有趣的是,使用前一个计划而不使用密钥的搜索执行得非常好,但后者需要大约23秒才能执行。我怎么能告诉MySQL遵循相同的执行计划?

0 个答案:

没有答案