所以我有这个查询
EXPLAIN SELECT r.* FROM r_table r
LEFT JOIN f_table f ON f.id = r.fid
LEFT JOIN f_table ff ON r.fid = 0 AND r.type = 'f' AND r.id = ff.id
WHERE (r.fid = 0 AND ff.cid = 421563) OR (r.fid <> 0 AND f.cid = 421563);
它正在表r上执行全表扫描
解释输出:
1 SIMPLE r ALL Index1 2314 Using where
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 r.fid 1 Using where
1 SIMPLE ff eq_ref PRIMARY PRIMARY 4 r.id 1 Using where
如何修改此查询以使其不执行全表扫描? 我知道我可以使用UNION,但除非必要,否则我宁愿不做UNION。
将查询重写为UNION确实有效......这是UNION查询
EXPLAIN SELECT r.* FROM r_table r
LEFT JOIN f_table f ON r.fid <> 0 AND f.id = r.fid
WHERE f.cid = 421563
UNION SELECT r.* FROM r_table r
LEFT JOIN f_table ff ON r.fid = 0 AND r.obj_type = 'f' AND r.obj_id = ff.id
WHERE ff.cid = 421563;
并解释输出
'2', 'UNION', 'ff', 'ref', 'PRIMARY,cid', 'cid', '4', 'const', '2', 'Using where; Using index'
'2', 'UNION', 'r', 'ref', 'Index1,obj_id_type', 'Index1', '13', 'const,const,ff.id', '1', 'Using where'
'1', 'PRIMARY', 'f', 'ref', 'PRIMARY,cid', 'cid', '4', 'const', '2', 'Using where; Using index'
'1', 'PRIMARY', 'r', 'ref', 'Index1', 'Index1', '4', 'f.id', '1', ''
NULL, 'UNION RESULT', '<union1,2>', 'ALL', NULL, NULL, NULL, NULL, NULL, ''
但是再一次,我宁愿不为这个
做一个UNION答案 0 :(得分:0)
只需将ff.cid和f.cid上的过滤器从where子句移动到连接即可。事实上,由于你正在进行左连接,所以你必须这样做。