• Oracle数据库查询高效分页


    Oracle数据库查询高效分页

     

            由于网页渲染速度的影响,在C/S程序中那种一个Grid包含几千、上万行的数据基本上在网页是无法展现的,因此一般采用分页的形式显示(也可能采用Visual Srolling方式加载的,企业应用系统的不是很常见),ASP.NET 的数据控件一般带有分页功能,3.5以后还提供了单独的分页控件,也有用过AspNetPager这个第三方的组件。

           分页的控件实在很方便,以前的处理方式就是数据都拿出来,然后由控件进行处理,一般数据量不大的时候应该说感觉不出来优劣,但由于每次从数据库取的时候都是取所有的数据,肯定会增加数据库的压力,传输的数据库多了对网络带宽也会产生压力的。很有可能查出来1万条数据,最后显示只用到启用50条,翻页的时候又重新去查1万条数据,显示之后的的又50条。

           以下的分页SQL比较常见的,在SQL Server也有对应的使用TOP关键字的版本,记得刚学Oralce的时候就想着怎么不能rownum between minValue and maxValue的用法。与最初的疑惑的原理一样,rownum是在查询过程中生成的,因此以下的SQL其实是查出来5300行,然后扔掉了前面5000行,返回后面的300行。当然这种已经进了一大步的,由数据库返回的数据变少的,只是当查询的页数比较大的时候,查询还是存在一定的浪费。

    1
    2
    3
    4
    5
    select *
      from (select a.*, rownum as rnum
              from (select * from yz_bingrenyz) a
             where rownum <=5300)
     where rnum >= 5000

           Linq提供了Skip和Take的API可以用于分页,由于使用的是Entity Framework,在好奇的驱使下用EFProfiler查看生成的SQL,才知道这样以下分页更好。 主要就是使用了row_numer()over()这样的分析函数,可以直接找到那第5000行开始的地方,然后在取出30行就行了。

    1
    2
    3
    4
    5
    6
    select *
      from (select *
              from (select t.*, row_number() OVER(ORDER BY null) AS "row_number"
                      from yz_bingrenyz t) p
             where p."row_number" > 5000) q
     where rownum <= 300

    比较分析:

            本机测试前者耗时1.3s,后者仅0.25s,从以下的执行计划也能看出差异来。

    image

    image

    实际应用

           如果每次查询都要写这种SQL那肯定比较麻烦,可以采用存储过程进行封装,但由于要动态执行SQL,效率肯定又要打折扣,所以在ASP.NET中用C#封装函数比较好,对于没有使用实体框架的而用ADO.NET的,传入表名 、主键名、页数、要取的行数作为参数,用DBCommand进行执行返回结果即可。

  • 相关阅读:
    吊打996,来了?!
    微软开源浏览器自动化工具Playwright for Python(附源码)
    从0到1开始建设安全测试体系
    网友爆料vivo将取消大小周,不降薪,官方证实消息属实
    认识了一个在华为任职的50岁程序员!
    漫画:什么是自动驾驶?
    中国十大杰出人物
    最难调试修复的 bug 是怎样的?
    “十年不升职多得是,四年算什么”
    appium+pytest实现APP并发测试
  • 原文地址:https://www.cnblogs.com/gaohao/p/2955707.html
Copyright © 2020-2023  润新知