MySQL 中的 FORCE INDEX - 我把它放在哪里?

Posted

技术标签:

【中文标题】MySQL 中的 FORCE INDEX - 我把它放在哪里?【英文标题】:FORCE INDEX in MySQL - where do I put it? 【发布时间】:2013-10-04 09:46:00 【问题描述】:

我有以下 mysql 查询,它工作得很好。除了我需要添加一个FORCE INDEX 并且我不确定我必须在哪里执行此操作。我几乎尝试了每个位置,但总是收到 MySQL 错误。我做错了什么?

这是原始查询:

$sql_select_recent_items = $db->query("SELECT * FROM (SELECT owner_id, product_id, start_time, price, currency, name, closed, active, approved, deleted, creation_in_progress FROM db_products ORDER BY start_time DESC) as resultstable
WHERE resultstable.closed=0 AND resultstable.active=1 AND resultstable.approved=1 AND resultstable.deleted=0 AND resultstable.creation_in_progress=0
GROUP BY resultstable.owner_id
ORDER BY start_time DESC");

查询是以这种方式构造的,因此我可以在GROUP BY 之前执行ORDER BY,以防您想知道。

我需要补充的是:

FORCE INDEX (products_start_time)

我几乎在所有地方都尝试过,但没有成功,这让我相信我缺少更复杂的东西?

【问题讨论】:

【参考方案1】:

index 提示的语法记录在此:http://dev.mysql.com/doc/refman/5.6/en/index-hints.html

FORCE INDEX 紧跟在表引用之后:

SELECT * FROM (
    SELECT owner_id,
           product_id,
           start_time,
           price,
           currency,
           name,
           closed,
           active,
           approved,
           deleted,
           creation_in_progress
    FROM db_products FORCE INDEX (products_start_time)
    ORDER BY start_time DESC
) as resultstable
WHERE resultstable.closed = 0
      AND resultstable.active = 1
      AND resultstable.approved = 1
      AND resultstable.deleted = 0
      AND resultstable.creation_in_progress = 0
GROUP BY resultstable.owner_id
ORDER BY start_time DESC

警告:

如果您在GROUP BY 之前使用ORDER BY 来获取每个owner_id 的最新条目,那么您正在使用MySQL 的非标准和未记录的行为来执行此操作。

不能保证它会在 MySQL 的未来版本中继续工作,并且查询可能在任何其他 RDBMS 中都是错误的。

搜索greatest-n-per-group 标签,了解此类查询的更好解决方案的许多解释。

【讨论】:

【参考方案2】:

FORCE_INDEX 将在 MySQL 8 之后被弃用:

Thus, you should expect USE INDEX, FORCE INDEX, and IGNORE INDEX to be deprecated in 
a future release of MySQL, and at some time thereafter to be removed altogether.

https://dev.mysql.com/doc/refman/8.0/en/index-hints.html

对于 v8,您应该改用 JOIN_INDEXGROUP_INDEXORDER_INDEXINDEX

从文档中,您可以了解到这些具有细微差别的含义,与以前的功能相比,可以更细粒度地控制您告诉优化器的内容。您可以阅读完整的详细信息in the docs,但如果您想要的只是“强制索引”的等价物,您可以通过在 SELECT 之后的特殊注释中指定表和索引来做到这一点:

SELECT /*+ index(table_name index_name) */ col1, col2 FROM table_name;

【讨论】:

以上是关于MySQL 中的 FORCE INDEX - 我把它放在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

mysql force index 简单使用

Mysql force index和ignore index 使用实例

MySQL force Index 强制索引概述

在 mysql 查询中使用 force index 子句可能有啥缺点? [关闭]

mysql force index 优化案例

mysql force index() 强制索引的使用