当您ORDER BY
在与UNION
mysql 结合使用的子查询中使用ORDER BY
子句时,将优化该子句。
这是因为默认情况下,a UNION
返回无序列表,因此a ORDER BY
不会执行任何操作。
在文档中提到了优化,并说:
要将ORDER BY或LIMIT应用于单个SELECT,请将子句放在包围SELECT的括号内:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
但是,对单个SELECT语句使用ORDER BY并不意味着行在最终结果中出现的顺序,因为UNION默认情况下会产生一组无序的行。因此,在这种情况下,ORDER BY的使用通常与LIMIT结合使用,因此,它可以用于确定要为SELECT检索的所选行的子集,即使它不一定影响SELECT中的那些行的顺序。最终的UNION结果。如果ORDER BY在SELECT中没有LIMIT出现,则会对其进行优化,因为它始终无效。
最后一句话有点误导,因为它应该起作用。当您需要在子查询中进行排序时,这种优化会导致问题。
要强制MySQL不执行此优化,可以添加LIMIT子句,如下所示:
(SELECT 1 AS rank, id, add_date FROM my_table WHERE distance < 5 ORDER BY add_date LIMIT 9999999999)
UNION ALL
(SELECT 2 AS rank, id, add_date FROM my_table WHERE distance BETWEEN 5 AND 15 ORDER BY rank LIMIT 9999999999)
UNION ALL
(SELECT 3 AS rank, id, add_date from my_table WHERE distance BETWEEN 5 and 15 ORDER BY id LIMIT 9999999999)
高LIMIT
表示OFFSET
如果要执行诸如分页之类的操作,则可以在整体查询上添加一个。
这还为您带来了额外的好处,就是能够ORDER BY
为每个联合设置不同的列。