MySQL、Oracle和SQL Server的分页查询

假设当前是第pageno页,每页有pagesize条记录,现在分别用mysql、oracle和sql server分页查询student表。

1、mysql的分页查询: 

1 select
2     *
3 from
4     student
5 limit (pageno - 1) * pagesize,pagesize;

理解:(limit n,m)  =>从第n行开始取m条记录,n从0开始算。

2、oracel的分页查询:

 1 select
 2     *
 3 from
 4     (
 5         select
 6            s.*, rownum rn 
 7         from
 8            (select * from student) s
 9         where
10             rownum <= pageno * pagesize
11     )
12 where
13     rn > (pageno - 1) * pagesize

或者

 1 select
 2     *
 3 from
 4     (
 5         select
 6            s.*, rownum rn 
 7         from
 8            (select * from student) s
11     )
12 where
13      rn between  (pageno - 1) * pagesize and  pageno * pagesize

理解:假设pageno = 1,pagesize = 10,先从student表取出行号小于等于10的记录,然后再从这些记录取出rn大于0的记录,从而达到分页目的。rownum从1开始。

分析:对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。

这是由于cbo 优化模式下,oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件where rownum <=

pageno * pagesize就可以被oracle推入到内层查询中,这样oracle查询的结果一旦超过了rownum限制条件,就终止查询将结果返回了。

而第二个查询语句,由于查询条件between (pageno – 1) * pagesize and pageno * pagesize是存在于查询的第三层,而oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道rn代表什么)。因此,对于第二个查询语句,oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。

3、sql server分页查询:

 1 select
 2     top pagesize *
 3 from
 4     (
 5         select
 6             row_number () over (order by id asc) rownumber ,*
 7         from
 8             student
 9     ) a
10 where
11     a.rownumber > (pageno - 1) * pagesize

 理解:假设pageno = 1,pagesize = 10,先按照student表的id升序排序,rownumber作为行号,然后再取出从第1行开始的10条记录。

  分页查询有的数据库可能有几种方式,这里写的可能也不是效率最高的查询方式,但这是我用的最顺手的分页查询,如果有兴趣也可以对其他的分页查询的方式研究一下。

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐