我知道我可以通过使用FORCE INDEX (abc)关键字来更改MySQL执行查询的方式。但是有没有办法改变执行顺序呢?
我的查询如下所示:
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。
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行。如果我将查询更改为
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:以下是一些信息:
关键是mysql应该开始查询表a,并按照c的方式工作,而不是反过来。为实现这一目标所做的任何改变。
解决方案:不完全是我想要的,但这似乎是有效的:
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)发布于 2010-08-11 20:59:03
也许你需要使用STRAIGHT_JOIN。
http://dev.mysql.com/doc/refman/5.0/en/join.html
STRAIGHT_JOIN类似于JOIN,不同之处在于左表总是在右表之前读取。这可用于连接优化器将表按错误顺序放置的那些(少数)情况。
发布于 2010-08-11 15:29:19
您可以使用强制索引来强制执行顺序,我以前也这样做过。
如果你仔细想想,对于你选择的任何索引,通常只有一个顺序可以查询表。
在这种情况下,如果您希望MySQL首先开始查询a,请确保对b强制的索引是包含b.table1_id的索引。如果已经先查询了a,那么MySQL将只能使用该索引。
发布于 2010-08-11 15:28:11
https://stackoverflow.com/questions/3456134
复制相似问题