首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法强制MySQL执行顺序?

有没有办法强制MySQL执行顺序?
EN

Stack Overflow用户
提问于 2010-08-11 15:17:19
回答 3查看 16.6K关注 0票数 26

我知道我可以通过使用FORCE INDEX (abc)关键字来更改MySQL执行查询的方式。但是有没有办法改变执行顺序呢?

我的查询如下所示:

代码语言:javascript
复制
SELECT c.*
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1_id
INNER JOIN table3 c ON b.itemid = c.itemid
WHERE a.itemtype = 1
  AND a.busy = 1
  AND b.something = 0
  AND b.acolumn = 2
  AND c.itemid = 123456

对于我使用的每个关系/约束,我都有一个键。如果我在这条语句上运行explain,我会看到mysql首先开始查询c。

代码语言:javascript
复制
id    select_type    table    type
1     SIMPLE         c        ref
2     SIMPLE         b        ref
3     SIMPLE         a        eq_ref

然而,我知道按a -> b -> c顺序查询会更快(我已经证明了这一点),有没有办法告诉mysql使用特定的顺序?

更新:这就是我为什么知道a -> b -> c更快的原因。

上面的查询耗时1.9秒完成,并返回7行。如果我将查询更改为

代码语言:javascript
复制
SELECT c.*
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1_id
INNER JOIN table3 c ON b.itemid = c.itemid
WHERE a.itemtype = 1
  AND a.busy = 1
  AND b.something = 0
  AND b.acolumn = 2
HAVING c.itemid = 123456

查询在0.01秒内完成(没有使用having I get 10.000行)。然而,这并不是一个优雅的解决方案,因为这个查询是一个简化的示例。在现实世界中,我有从c到其他表的连接。由于HAVING是一个在整个结果上执行的过滤器,这意味着我将从数据库中提取比nescessary多一些数量的记录。

Edit2:以下是一些信息:

  • 此查询中的变量部分为c.itemid。其他的都是固定值,它们不会被设置得很好,mysql会为我选择正确的值,在a和b之间有一个1:n的关系(索引change.
  • Indexes是used)
  • between b,c是多对多关系(index IDX_ITEMID是used)

关键是mysql应该开始查询表a,并按照c的方式工作,而不是反过来。为实现这一目标所做的任何改变。

解决方案:不完全是我想要的,但这似乎是有效的:

代码语言:javascript
复制
SELECT c.*
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1_id
INNER JOIN table3 c ON b.itemid = c.itemid
WHERE a.itemtype = 1
  AND a.busy = 1
  AND b.something = 0
  AND b.acolumn = 2
  AND c.itemid = 123456
  AND f.id IN (
         SELECT DISTINCT table2.id FROM table1
         INNER JOIN table2 ON table1.id = table2.table1_id
         WHERE table1.itemtype = 1 AND table1.busy = 1)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-08-11 20:59:03

也许你需要使用STRAIGHT_JOIN

http://dev.mysql.com/doc/refman/5.0/en/join.html

STRAIGHT_JOIN类似于JOIN,不同之处在于左表总是在右表之前读取。这可用于连接优化器将表按错误顺序放置的那些(少数)情况。

票数 43
EN

Stack Overflow用户

发布于 2010-08-11 15:29:19

您可以使用强制索引来强制执行顺序,我以前也这样做过。

如果你仔细想想,对于你选择的任何索引,通常只有一个顺序可以查询表。

在这种情况下,如果您希望MySQL首先开始查询a,请确保对b强制的索引是包含b.table1_id的索引。如果已经先查询了a,那么MySQL将只能使用该索引。

票数 4
EN

Stack Overflow用户

发布于 2010-08-11 15:28:11

您可以通过两种方式尝试重写

  • 将一些WHERE条件引入到JOIN
  • introduce子查询中,即使它们不是

所必需的

这两件事都可能会影响计划者。

不过,首先要检查的是你的stats是否是最新的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3456134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档