以下两个SQL语句是否始终生成相同的结果集?
1. SELECT * FROM MyTable where Status='0' order by StartTime asc limit 10
2. SELECT * FROM (SELECT * FROM MyTable where Status='0' order by StartTime asc) limit 10
答案 0 :(得分:7)
是的,但订购子查询可能是一个不好的习惯。您可以在第二个示例中在子查询之外添加更多ORDER BY
,例如
SELECT *
FROM (SELECT *
FROM Test
ORDER BY ID ASC
) AS A
ORDER BY ID DESC
LIMIT 10;
SQLite仍在内部查询上执行ORDER BY
,然后在外部查询中再次对它们进行排序。不必要的资源浪费。
我已经完成了SQL Fiddle演示,因此您可以查看每个的执行计划。
答案 1 :(得分:6)
否即可。首先是因为StartTime
列可能没有UNIQUE
约束。因此,即使第一个查询也可能并不总是产生相同的结果 - 与它本身!
其次,即使从来没有两行具有相同的StartTime,答案仍然是否定。
第一个语句将始终在StartTime
上排序并生成前10行。第二个查询可能会生成相同的结果集,但只能生成一个原始优化器,它不能理解子查询中的ORDER BY
是多余的。并且只有执行计划包括此订购阶段。
SQLite查询优化器可能(目前)不是很明亮并且做到这一点(实际上不知道,我们必须检查SQLite *的源代码)。因此,似乎两个查询始终产生相同的结果。尽管如此,依靠它并不是一个好主意。你永远不知道在未来的SQLite版本中会做出哪些改变。
我认为在任何DBMS中使用LIMIT
而不使用ORDER BY
并不是一个好习惯。它现在可以工作,但您永远不知道应用程序将使用这些查询多长时间。当SQLite升级或DBMS发生变化时,您可能不在身边。
(*)@ Gareth的链接提供了执行计划,该计划表明当前的SQLite代码足以执行冗余排序。