MySQL FORCE索引

时间:2019-11-20 08:52:15  来源:igfitidea点击:

简介:在本教程中,您将学习如何使用MySQL FORCE INDEX强制查询优化器使用指定的命名索引。

查询优化器是MySQL数据库服务器中的一个组件,它为SQL语句制定了最佳的执行计划。

查询优化器使用可用的统计信息提出所有候选计划中成本最低的计划。

例如,查询可能会请求价格在10到80之间的产品。
如果统计数据表明80%的产品具有这些价​​格范围,则它可能会确定全表扫描是最有效的。
但是,如果统计数据表明很少有产品具有这些价​​格范围,那么在读取索引后再进行表访问可能比全表扫描更快,更有效。

如果查询优化器忽略了索引,则可以使用FORCE INDEX提示来指示它使用索引。

下面说明了FORCE INDEX提示语法:

SELECT * 
FROM table_name 
FORCE INDEX (index_list)
WHERE condition;

在这种语法中,将FORCE INDEX子句放在FROM子句之后,然后是查询优化器必须使用的命名索引列表。

MySQL FORCE INDEX示例

我们将使用示例数据库中的产品表进行演示。

以下语句显示产品表的索引:

SHOW INDEXES FROM products;

要查找价格在10到80之间的产品,请使用以下语句:

SELECT 
    productName, 
    buyPrice
FROM
    products
WHERE
    buyPrice BETWEEN 10 AND 80
ORDER BY buyPrice;

您可能会猜到,要返回产品,查询优化器必须扫描整个表,因为buyPrice列没有可用的索引:

EXPLAIN SELECT 
    productName, 
    buyPrice
FROM
    products
WHERE
    buyPrice BETWEEN 10 AND 80
ORDER BY buyPrice;

让我们为buyPrice列创建一个索引:

CREATE INDEX idx_buyprice ON products(buyPrice);

并再次执行查询:

EXPLAIN SELECT 
    productName, 
    buyPrice
FROM
    products
WHERE
    buyPrice BETWEEN 10 AND 80
ORDER BY buyPrice;

令人惊讶的是,即使存在索引,查询优化也没有将索引用于buyPrice列。
原因是查询返回了产品表的110行中的94行,因此查询优化器决定执行全表扫描。

要强制查询优化器使用idx_buyprice索引,请使用以下查询:

SELECT 
    productName, buyPrice
FROM
    products 
FORCE INDEX (idx_buyPrice)
WHERE
    buyPrice BETWEEN 10 AND 80
ORDER BY buyPrice;

这次,该索引用于查找产品,如以下EXPLAIN语句所示:

EXPLAIN SELECT 
    productName, buyPrice
FROM
    products 
FORCE INDEX (idx_buyprice)
WHERE
    buyPrice BETWEEN 10 AND 80
ORDER BY buyPrice;

这是输出:

在本教程中,您学习了如何使用MySQL FORCE INDEX提示来强制查询优化器使用命名索引列表。