Jür*_*ock 24 mysql performance sql-execution-plan
我知道我可以通过使用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
Run Code Online (Sandbox Code Playgroud)
我有一个关键用于我使用的每个关系/约束.如果我在这个语句上运行解释,我看到mysql首先开始查询c.
id select_type table type
1 SIMPLE c ref
2 SIMPLE b ref
3 SIMPLE a eq_ref
Run Code Online (Sandbox Code Playgroud)
但是,我知道在命令中查询 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
Run Code Online (Sandbox Code Playgroud)
查询在0.01秒内完成(不使用我获得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)
Run Code Online (Sandbox Code Playgroud)
Ham*_*ite 37
也许你需要使用STRAIGHT_JOIN
.
http://dev.mysql.com/doc/refman/5.0/en/join.html
STRAIGHT_JOIN
类似于JOIN
,除了左表总是在右表之前读取.这可以用于连接优化器以错误顺序放置表的那些(少数)情况.
归档时间: |
|
查看次数: |
13374 次 |
最近记录: |