MariaDB / MySQL:存在左连接时忽略索引提示

Posted

技术标签:

【中文标题】MariaDB / MySQL:存在左连接时忽略索引提示【英文标题】:MariaDB / MySQL: Index hint ignored when there is left join 【发布时间】:2019-05-07 17:17:51 【问题描述】:

考虑发货和订单表中都有 2M 条记录。

SELECT DISTINCT
    s0_.id         AS id0,
    s0_.updated_at AS updated_at1
FROM
    `shipment` s0_
        LEFT JOIN `order` s1_ ON s0_.order_id = s1_.id -- These line
        LEFT JOIN `address` s2_ ON s1_.shipping_address_id = s2_.id -- These line
ORDER BY s0_.updated_at DESC
LIMIT 20 OFFSET 0

如果我删除左连接 MariaDB 将使用指定的索引,为什么?有什么解决办法吗?

此 SQL 由库生成,我修复它的选项有限。

此 SQL 由库生成,我修复它的选项有限。

此 SQL 由库生成,我修复它的选项有限。

此 SQL 由库生成,我修复它的选项有限。

此 SQL 由库生成,我修复它的选项有限。

不要让我删除它。我知道它没有用。而且我认为查询优化器也需要考虑,因为它只是 LEFT JOIN。

我正在使用 MariaDB 10.1

【问题讨论】:

EXPLAIN query and SHOW CREATE TABLE shipment and SHOW CREATE TABLE orders 看看你有什么索引。 order by limit clauses 需要进行一些优化。 LEFT JOINs 报告为 Pagerfanta 库中的错误 :-) 对您使用的代码负责。 你可以分叉项目并修复它。 github.com/whiteoctober/Pagerfanta 我真的想删除这个问题 【参考方案1】:

left join 需要先找到货件的order_id,然后才订购输出。

强制索引通常是错误的做法,即使它可以发现一些东西。

使用shipment(order_id, updated_at) 的复合索引,您无需强制使用索引。

参考:compound indexes query optimization

【讨论】:

我认为你是对的,但是看到优化器像这样处理这个查询也是愚蠢的,因为它只是 LEFT JOIN 你能检查更新的问题吗?如果只有一个直接左连接但不像更新后的查询,您的解决方案就可以工作 当我删除 DISTINCT 时,它很快。 s0_.id 已经是主键。我需要添加唯一约束吗?它会起作用吗? 主键始终是唯一的,所以是的,不需要 distinct。 EXPLAINSHOW CREATE TABLE 请提供信息。 addresses 上的附加连接不用于结果集或过滤的任何方面。 整个查询由 Pagerfanta 生成

以上是关于MariaDB / MySQL:存在左连接时忽略索引提示的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL之內链接 左链接 右链接 区别

MySQL组合索引和最左匹配原则

左连接,右连接与内连接

Mysql:使用左连接选择未按预期工作

如何将LabVIEW连接到MySQL MariaDB

MySQL 索引优化与子查询与左连接