58

我有以下 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");

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

我需要补充的是:

FORCE INDEX (products_start_time)

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

4

2 回答 2

79

索引提示的语法记录在这里:
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

警告:

如果您使用ORDER BYbeforeGROUP BY来获取最新条目 per owner_id,那么您正在使用 MySQL 的非标准且未记录的行为来执行此操作。

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

搜索标记以获取此类查询的更好解决方案的许多解释。

于 2013-09-28T00:30:12.887 回答
9

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_INDEX, GROUP_INDEX, ORDER_INDEX, 而不是。INDEX

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

SELECT /*+ index(table_name index_name) */ col1, col2 FROM table_name;
于 2021-02-24T13:45:08.947 回答