在sqlite SQL语句中结合order by子句使用limit

时间:2012-05-03 10:42:28

标签: sql sqlite

以下两个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

2 个答案:

答案 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代码足以执行冗余排序。