rownum / 获取前 n 行

use*_*926 2 sql db2 db2-luw

select * from Schem.Customer 
  where cust='20' and cust_id >= '890127'
  and rownum between 1 and 2 order by cust, cust_id;
Run Code Online (Sandbox Code Playgroud)

执行时间约2分10秒

   select * from Schem.Customer where cust='20' 
   and cust_id >= '890127' 
   order by cust, cust_id fetch first 2 rows only ;
Run Code Online (Sandbox Code Playgroud)

执行时间约 00.069 ms

执行时间有很大差异,但结果是相同的。我的团队不会采用后来的一种。别问为什么。

那么 Rownum 和 fetch 前 2 行有什么区别,我应该做什么来改进或说服任何人采用。

数据库管理系统:DB2 LUW

Ram*_*lat 6

尽管两个 SQL 最终都会给出相同的结果集,但这只发生在您的数据上。结果集很有可能会有所不同。让我解释一下原因。

我会让你的 SQL 更简单一些,以便于理解:

SELECT * FROM customer
WHERE ROWNUM BETWEEN 1 AND 2;
Run Code Online (Sandbox Code Playgroud)

在此 SQL 中,您只需要第一行和第二行。没关系。DB2 将优化您的查询,并且永远不会查找超出第 2 行的行。因为只有前 2 行符合您的查询条件。

然后添加ORDER BY子句:

SELECT * FROM customer
WHERE ROWNUM BETWEEN 1 AND 2;
ORDER BY cust, cust_id;
Run Code Online (Sandbox Code Playgroud)

在本例中,DB2 首先获取 2 行,然后按 cust 和 cust_id 对它们进行排序。然后发送给客户(您)。到目前为止,一切都很好。但是,如果您想先按 cust 和 cust_id 排序,然后请求前 2 行怎么办?他们之间有很大的区别。

这是本例的简化 SQL:

SELECT * FROM customer
ORDER BY cust, cust_id
FETCH FIRST 2 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)

在此 SQL 中,所有行都符合查询条件,因此 DB2 获取所有行,然后对它们进行排序,然后将前 2 行发送到客户端。

在您的情况下,两个查询给出相同的结果,因为前 2 行已按 cust 和 cust_id 排序。但如果前 2 行具有不同的 cust 和 cust_id 值,则它将不起作用。

order by之后FETCH FIRST n ROWS有一个关于此的提示,这意味着 DB2 对结果进行排序,然后检索前 n 行。