首页 > 数据库 >SQL分页优化三 降序排序+分页

SQL分页优化三 降序排序+分页

时间:2023-08-05 16:01:57浏览次数:30  
标签:10 00 分页 降序 object SQL test id select

测试验证

如下SQL: 
select * 
 from (select * 
         from (select a.*, rownum rn 
                 from (select * 
                         from test 
                        order by object_id,object_name desc) a) 
        where rownum <= 10) 
where rn >= 1;

创建索引:

SQL> create index idx_test_id_name on test(object_id,object_name desc,0);

Index created.
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------
SQL_ID  4ksmz0g2zjwtj, child number 0
-------------------------------------
select *   from (select *           from (select a.*, rownum rn
          from (select /*+index(test idx_test_id_name)*/
           *                           from test
    order by object_id, object_name desc) a)          where rownum <=
10)  where rn >= 1

Plan hash value: 445348578

---------------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name             | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                  |      1 |        |     10 |00:00:00.01 |       5 |      4 |
|*  1 |  VIEW                            |                  |      1 |     10 |     10 |00:00:00.01 |       5 |      4 |
|*  2 |   COUNT STOPKEY                  |                  |      1 |        |     10 |00:00:00.01 |       5 |      4 |
|   3 |    VIEW                          |                  |      1 |  74510 |     10 |00:00:00.01 |       5 |      4 |
|   4 |     COUNT                        |                  |      1 |        |     10 |00:00:00.01 |       5 |      4 |
|   5 |      VIEW                        |                  |      1 |  74510 |     10 |00:00:00.01 |       5 |      4 |
|   6 |       TABLE ACCESS BY INDEX ROWID| TEST             |      1 |  74510 |     10 |00:00:00.01 |       5 |      4 |
|   7 |        INDEX FULL SCAN           | IDX_TEST_ID_NAME |      1 |  74510 |     10 |00:00:00.01 |       3 |      4 |
-----------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("RN">=1)
   2 - filter(ROWNUM<=10)

如果创建索引时,将object_name在前,object_id列在后,这个时候,索引中列先后顺序与分页语句中排序列先后顺序不一致,强制走索引,就会出现sort order by。因为索引的顺序与排序的顺序不一致,所以需要从索引获取数据之后在排序,有排序就会出现sort order by。
测试:

SQL> create index idx_test_name_id on test(object_name,object_id,0);

Index created.

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));


PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  a80tzbw35yk28, child number 0
-------------------------------------
select *   from (select *           from (select a.*, rownum rn
          from (select /*+index(test idx_test_name_id)*/
           *                           from test
    order by object_id, object_name desc) a)          where rownum <=
10)  where rn >= 1

Plan hash value: 2869317785

---------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name             | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                  |      1 |        |     10 |00:00:00.11 |   37338 |    431 |       |       |          |
|*  1 |  VIEW                             |                  |      1 |     10 |     10 |00:00:00.11 |   37338 |    431 |       |       |          |
|*  2 |   COUNT STOPKEY                   |                  |      1 |        |     10 |00:00:00.11 |   37338 |    431 |       |       |          |
|   3 |    VIEW                           |                  |      1 |  74510 |     10 |00:00:00.11 |   37338 |    431 |       |       |          |
|   4 |     COUNT                         |                  |      1 |        |     10 |00:00:00.11 |   37338 |    431 |       |       |          |
|   5 |      VIEW                         |                  |      1 |  74510 |     10 |00:00:00.11 |   37338 |    431 |       |       |          |
|   6 |       SORT ORDER BY               |                  |      1 |  74510 |     10 |00:00:00.11 |   37338 |    431 |    10M|  1282K|    9M (0)|
|   7 |        TABLE ACCESS BY INDEX ROWID| TEST             |      1 |  74510 |  72571 |00:00:00.08 |   37338 |    431 |       |       |          |
|   8 |         INDEX FULL SCAN           | IDX_TEST_NAME_ID |      1 |  74510 |  72571 |00:00:00.05 |     431 |    431 |       |       |          |
---------------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("RN">=1)
   2 - filter(ROWNUM<=10)

从执行计划看到,出现了sort order by,这就说明分页语句没有利用到索引已经排好序的特性,执行计划是错误的,这时需要创建正确的索引。

标签:10,00,分页,降序,object,SQL,test,id,select
From: https://blog.51cto.com/u_13482808/6976287

相关文章

  • SQL分页优化四 等值+非等值+order by分页
    测试验证现有如下SQL,每页显示10条:select*fromtestwhereowner='SYS'andobject_id>1000orderbyobject_name;select*from(select*from(selecta.*,rownumrnfrom(select*fromt......
  • SQL分页优化五 like+非等值+order by分页
    测试验证如下SQL:select*from(select*from(selecta.*,rownumrnfrom(select*fromtestwhereownerlike'SYS%'......
  • openGauss的SQL引擎在3.1.0版本中做了哪些优化?
    openGauss的SQL引擎在3.1.0版本中做了哪些优化?收录于合集#技术干货83个查询执行能力对数据库来说至关重要,这直接决定了查询语句生成的执行计划以何种方式进行执行,如果哪个执行算子的执行表现不好,将会对数据库的整体性能产生极大的影响。同时,执行算子的实现也极大考验一款数据库的工......
  • 数据库迁移系列】从MySQL到openGauss的数据库对象迁移实践
    数据库迁移系列】从MySQL到openGauss的数据库对象迁移实践原创酷哥[openGauss](javascript:void(0);)2022-11-0718:03发表于广东9月30日新发布的openGauss3.1.0版本,工具的全量迁移和增量迁移的性能不但有了全面提升,而且支持数据库对象视图、触发器、自定义函数、存储过程的......
  • SQL-去除最大值与最小值求均值的问题
    背景今天有同事问我一道关于数据库SQL的面试题,我刚开始随便给了一个思路,后来思索发现这个思路有漏洞,于是总结下来,仅供参考。问题:薪水表中是员工薪水的基本信息,包括雇员编号,和薪水,查询除去最高、最低薪水后的平均薪水。一、薪水表信息CREATETABLE`salaries`(`emp_n......
  • Docker-Compose 一键部署mysql及初始化sql脚本
    1.部署前提:服务器具备docker和docker-compose环境2.镜像准备:-mysql:DockerFile文件:FROMmysql:5.7.41COPY*.sql/docker-entrypoint-initdb.d/初始化sql脚本xxx.sql放在DockerFile文件同级目录下执行指令:dockerbuild-fdockerfile_mysql-tmysql:1.0.0.......
  • Sqlmap的使用
    1、get型提交sqlmap.py-u+网址sqlmap.py-uhttp://127.0.0.1/sqli/Less-1/?id=1参数levellevel的等级越高,测试的等级越广,>=2时会检查cookie里的参数>=3时检查user-agent和refereer--dbs              查询所有的数据库sqlmap.py-uhttp://127.0.0.1/sql......
  • 老派Sql之必要,逆天,我在ef core中使用ado.net!
    Wlkr.Core.EFCore逆天,我在efcore中使用ado.net!老派Sql之必要当你开发生涯中基本只用一两种数据库当你觉得用EF的类写报表时很别扭当你觉自己的Sql(Server)语句写得出神入化当你觉自己的Sql(Server)语句比EF生成的更优化当你刚从.netframework转.netcore,还不知道sqls......
  • MySql之锁
    MySql之锁一、全局锁对整个数据库加锁应用:数据库所有表备份二、表级锁1.表锁分为两类:表共享读锁readlock表独占写锁writelock2.元数据锁避免DML语句和DDL语句的冲突问题3.意向锁:作用:针对行锁和表锁,当表中有行锁时,会同时加一把意向锁,表锁不用去逐行遍历是否加了行锁,......
  • 最简单的Qt连接MYSQL的方法
    最简单的Qt连接MYSQL的方法⭐当我试图在项目中连接本地的mysql时,反复出现:QMYSQLdrivernotloaded,显示没有成功加载mysql的驱动,在网上查询了很多教程和视频,大多为互相转载且老旧,耗费了大半天还是没有构建成功,通常的解决方法是在本地构建mysql驱动(通过安装qt时勾选的src选项里......