在MySQL手册中,index hinting上有一个页面,提到您可以为查询的特定部分指定索引提示。
您可以通过向提示添加
FOR
子句来指定索引提示的范围。这为优化器对查询处理的各个阶段的执行计划的选择提供了更细粒度的控制。要仅影响MySQL决定如何在表中查找行以及如何处理联接时使用的索引,请使用FOR JOIN
。要影响对行进行排序或分组的索引用法,请使用FOR ORDER BY
或FOR GROUP BY
。
然而,几乎没有关于它如何工作或在MySQL优化器中实际做什么的信息。在实践中,实际上改进任何东西似乎都可以忽略不计。
这是一个测试查询以及有关查询的说明:
SELECT
`property`.`primary_id` AS `id`
FROM `California` `property`
USE INDEX FOR JOIN (`Zipcode Bedrooms`)
USE INDEX FOR ORDER BY (`Zipcode Bathrooms`)
INNER JOIN `application_zipcodes` `az`
ON `az`.`application_id` = '18'
AND `az`.`zipcode` = `property`.`zipcode`
WHERE `property`.`city` = 'San Jose'
AND `property.`zipcode` = '95133'
AND `property`.property_type` = 'Residential'
AND `property`.`style` = 'Condominium'
AND `property`.`bedrooms` = '3'
ORDER BY `property`.`bathrooms` ASC
LIMIT 15
;
说明:
EXPLAIN SELECT `property`.`primary_id` AS `id` FROM `California` `property` USE INDEX FOR JOIN (`Zipcode Bedrooms`) USE INDEX FOR ORDER BY (`Zipcode Bathrooms`) INNER JOIN `application_zipcodes` `az` ON `az`.`application_id` = '18' AND `az`.`zipcode` = `property`.`zipcode` WHERE `property`.`city` = 'San Jose' AND `property.`zipcode` = '95133' AND `property`.property_type` = 'Residential' AND `property`.`style` = 'Condominium' AND `property`.`bedrooms` = '3' ORDER BY `property`.`bathrooms` ASC LIMIT 15\g
+------+-------------+----------+--------+---------------+---------+---------+------------------------------------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+--------+---------------+---------+---------+------------------------------------+------+----------------------------------------------------+
| 1 | SIMPLE | Property | ref | Zip Bed | Zip Bed | 17 | const,const | 2364 | Using index condition; Using where; Using filesort |
| 1 | SIMPLE | az | eq_ref | PRIMARY | PRIMARY | 7 | const,Property.zipcode | 1 | Using where; Using index |
+------+-------------+----------+--------+---------------+---------+---------+------------------------------------+------+----------------------------------------------------+
2 rows in set (0.01 sec)
总而言之,我基本上想知道如何使用索引范围,因为当我添加或删除行USE INDEX FOR ORDER BY (Zipcode Bathrooms)
时,这似乎没有做任何事情。
答案 0 :(得分:1)
我还没弄清楚如何使用多个提示。 MySQL每个SELECT
几乎不会使用多个索引。我所知道的唯一例外是" index merge",这与您的示例无关。
优化器通常专注于为WHERE
子句找到一个好的索引。如果它完全覆盖了WHERE
,没有任何"范围",那么它会检查是否有GROUP BY
和ORDER BY
字段,按正确的顺序使用。如果它可以处理所有WHERE, GROUP BY, and ORDER BY
,那么它实际上可以优化LIMIT
(但不是OFFSET
)。
如果优化程序无法使用所有WHERE
,那么它可能会进入ORDER BY
,希望避免使用" filesort" ORDER BY
否则需要。
这些都不允许不同子句的不同索引。单一提示可鼓励使用上述案例之一(上文)而不是另一案件;我不知道。
不要将utf8用于邮政编码;它使得比必要的东西更大(每个字符3个字节)。通常,缩小表的大小将有助于提高性能。或者,如果您有一个庞大的数据集,它可能会有很大帮助。 (避免I / O非常重要。)
Bathrooms
不是很有选择性;即使有可能也没有太大的收获。
az.application_id
是查询中的大扳手;它是什么?