Mysql WHERE语句中OR的全表扫描

Mysql WHERE语句中OR的全表扫描,mysql,sql,database,explain,Mysql,Sql,Database,Explain,所以我有这个疑问 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);

所以我有这个疑问

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);
如何修改此查询以使其不执行完整表扫描? 我知道我可能会使用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, ''

但是再一次,我不想为此进行联合,只需将ff.cid和f.cid上的过滤器从where子句移动到join。事实上,由于您正在进行左联接,因此无论如何都必须这样做。

我怀疑r.fid=0和r.type='f'不应该是ff_表联接的一部分。这些应该是where子句的一部分。由于r.fid列在这两种情况下都被使用,并且在查询中没有限制,我的理解是它必须扫描整个表以获取所有匹配的记录。因此,您只想在r.fid为0时加入ff_表?请怀疑即使是并集也不会有帮助,因为您要从r_表中获取每一行,就像您需要在r.fid上建立索引,可能还有ff.cid和f.cid。是否仍在进行全表扫描
'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, ''