数据准备

--创建基础数据表100W行

create table test07 as
select *
from (select generate_series(1, 1000000) id,
(random() * 1000)::int c1k,
(random() * 100000)::int c100k,
(random() * 1000000)::int c1m)
order by random(); alter table test07 add primary key (id);
create index test07_c1m on test07 (c1m);
create index test07_c1k on test07 (c1k);
create index test07_c100k on test07 (c100k);

测试SQL例子

--使用 c1k between 1 and 1 条件,决定读取行数占比
--使用 ROWNUM <= 10 条件 或者 LIMIT 10,决定输出行数占比
explain analyse
select *
from (select *
from test07
where c1k between 1 and 10
order by id
) t
where rownum <= 100
limit 100
;

SQL语句的执行计划

SQL语句,会产生两种执行计划

  • 计划一:根据排序列的索引,先排序后过滤

    QUERY PLAN
    -----------------------------------------------
    Limit (cost=0.42..592.06 rows=100 width=12) (actual time=0.124..9.451 rows=100 loops=1)
    -> Index Scan using test07_pkey on test07 (cost=0.42..52779.58 rows=8936 width=12) (actual time=0.123..9.438 rows=100 loops=1)
    Filter: ((c1k >= 1) AND (c1k <= 10))
    Rows Removed by Filter: 11258
    Planning Time: 0.192 ms
    Execution Time: 9.478 ms
  • 计划二:根据过滤列的索引,先过滤后排序

    QUERY PLAN
    -----------------------------------------------
    Count (cost=6553.38..6754.44 rows=0 width=12) (actual time=11.042..11.058 rows=100 loops=1)
    Stop Keys: (ROWNUM <= 100)
    -> Sort (cost=6553.38..6575.72 rows=8936 width=12) (actual time=11.038..11.046 rows=101 loops=1)
    Sort Key: test07.id
    Sort Method: quicksort Memory: 855kB
    -> Bitmap Heap Scan on test07 (cost=192.02..5966.93 rows=8936 width=12) (actual time=3.123..9.473 rows=10031 loops=1)
    Recheck Cond: ((c1k >= 1) AND (c1k <= 10))
    Heap Blocks: exact=4586
    -> Bitmap Index Scan on test07_c1k (cost=0.00..189.79 rows=8936 width=0) (actual time=2.033..2.033 rows=10031 loops=1)
    Index Cond: ((c1k >= 1) AND (c1k <= 10))
    Planning Time: 0.195 ms
    Execution Time: 11.093 ms

    各种情况的rownum与limit的比较

    • ROWNUM

      过滤比例 输出比例 计划模式 执行时长
      < 30% 1 ~ ALL 计划二 0.1ms ~ 130 ms
      explain (analyse,buffers )
      select *
      from (select *
      from test07
      where c1k between 1 and 300
      order by id
      ) t
      where rownum <= 100; QUERY PLAN
      -----------------------------------------------
      Count (cost=43557.67..50297.35 rows=0 width=16) (actual time=80.721..80.759 rows=100 loops=1)
      Stop Keys: (ROWNUM <= 100)
      Buffers: shared hit=6262
      -> Sort (cost=43557.67..44306.53 rows=299541 width=16) (actual time=80.717..80.744 rows=101 loops=1)
      Sort Key: test07.id
      Sort Method: quicksort Memory: 26355kB
      Buffers: shared hit=6262
      -> Bitmap Heap Scan on test07 (cost=6382.72..16310.84 rows=299541 width=16) (actual time=19.502..41.889 rows=300094 loops=1)
      Recheck Cond: ((c1k >= 1) AND (c1k <= 300))
      Heap Blocks: exact=5435
      Buffers: shared hit=6262
      -> Bitmap Index Scan on test07_c1k (cost=0.00..6307.84 rows=299541 width=0) (actual time=19.105..19.105 rows=300094 loops=1)
      Index Cond: ((c1k >= 1) AND (c1k <= 300))
      Buffers: shared hit=827
      Planning Time: 0.229 ms
      Execution Time: 80.801 ms
      过滤比例 输出比例 计划模式 执行时长
      < 30% 1 ~ ALL 计划一 0.1 ms ~ 400 ms
      explain (analyse,buffers )
      select /*+ indexscan(test07) */ *
      from (select *
      from test07
      where c1k between 1 and 300
      order by id
      ) t
      where rownum <= 100; QUERY PLAN
      -----------------------------------------------
      Count (cost=0.42..58767.29 rows=0 width=16) (actual time=0.031..0.643 rows=100 loops=1)
      Stop Keys: (ROWNUM <= 100)
      Buffers: shared hit=429
      -> Index Scan using test07_pkey on test07 (cost=0.42..52776.47 rows=299541 width=16) (actual time=0.028..0.611 rows=101 loops=1)
      Filter: ((c1k >= 1) AND (c1k <= 300))
      Rows Removed by Filter: 324
      Buffers: shared hit=429
      Planning Time: 0.261 ms
      Execution Time: 0.681 ms
      过滤比例 输出比例 计划模式 执行时长
      > 30% 1 ~ ALL 计划一 0.1ms ~ 400ms
      explain (analyse,buffers )
      select *
      from (select *
      from test07
      -- where c1m between (1000000*(1-0.320))::int and 1000000
      where c1k between 1 and 400
      order by id
      ) t
      where rownum <= 100; QUERY PLAN
      -----------------------------------------------
      Count (cost=0.42..60774.27 rows=0 width=16) (actual time=0.032..0.489 rows=100 loops=1)
      Stop Keys: (ROWNUM <= 100)
      Buffers: shared hit=304
      -> Index Scan using test07_pkey on test07 (cost=0.42..52776.47 rows=399890 width=16) (actual time=0.029..0.458 rows=101 loops=1)
      Filter: ((c1k >= 1) AND (c1k <= 400))
      Rows Removed by Filter: 200
      Buffers: shared hit=304
      Planning Time: 0.197 ms
      Execution Time: 0.526 ms
    • LIMIT

      过滤比例 输出比例 计划模式 执行时长
      > 5% < 1% 计划一 < 85 ms
      < 5% < 1% 计划二 < 25 ms
      > 5% > 1% 计划二 25 ms ~ 35 ms
      < 5% > 1% 计划一 25 ms ~ 35 ms

总结

使用ROWNUM 作为输出行数的条件,不考虑 “FIRST_ROWS”的需求,仅考虑过滤条件的索引。

LIMIT更为精细的权衡过滤条件,可以获得更好的执行计划和时长。如果希望从一个大表中,更快的获得“首页”数据,建议使用LIMIT。

KingbaseES rownum 与 limit 的 执行计划区别的更多相关文章

  1. MySQL---正确使用索引、limit分页、执行计划、慢日志查询

    正确使用索引 数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效.即使建立索引,索引也不会生效: - like '%xx' se ...

  2. Oracle执行计划 explain plan

    Rowid的概念:rowid是一个伪列,既然是伪列,那么这个列就不是用户定义,而是系统自己给加上的. 对每个表都有一个rowid的伪列,但是表中并不物理存储ROWID列的值.不过你可以像使用其它列那样 ...

  3. Oracle - SPM固定执行计划

    1. 通过dbms_xplan.display_cursor查看指定sql都有哪些执行计划 SQL> select * from table(dbms_xplan.display_cursor( ...

  4. 关于T-SQL重编译那点事,内联函数和表值函数在编译生成执行计划的区别

    本文出处:http://www.cnblogs.com/wy123/p/6266724.html 最近在学习 WITH RECOMPILE和OPTION(RECOMPILE)在重编译上的区别的时候,无 ...

  5. oracle_执行计划_谓词信息和数据获取(access and filter区别) (转)

    These two terms in the Predicate Information section indicate when the data source is reduced. Simpl ...

  6. MySQL执行计划extra中的using index 和 using where using index 的区别

    本文出处:http://www.cnblogs.com/wy123/p/7366486.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  7. 第二百八十八节,MySQL数据库-索引、limit分页、执行计划、慢日志查询

    MySQL数据库-索引.limit分页.执行计划.慢日志查询 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获 ...

  8. 正确使用索引(sql优化),limit分页优化,执行计划,慢日志查询

    查看表相关命令 - 查看表结构   desc 表名- 查看生成表的SQL   show create table 表名- 查看索引   show index from  表名 使用索引和不使用索引 由 ...

  9. KingbaseES 如何查看应用执行的SQL的执行计划

    通过explain ,我们可以获取特定SQL 的执行计划.但对于同一条SQL,不同的变量.不同的系统负荷,其执行计划可能不同.我们要如何取得SQL执行时间点的执行计划?KingbaseES 提供了 a ...

随机推荐

  1. Vue3.0系列——「vue3.0学习手册」第一期

    一.项目搭建 vite是尤大大开发的一款意图取代webpack的工具.其实现原理是利用ES6的import发送请求加载文件的特性.拦截这些请求,做一些编译,省去webpack冗长的打包时间.并将其与R ...

  2. python新建一个目录

    源码部分 import os # 创建目录 def mkdir(path): isExists = os.path.exists(path) if not isExists: os.makedirs( ...

  3. 聊聊 RPA 方向的规划:简单有价值的事情长期坚持做

    「简单有价值的事情长期坚持做」 这是成功最简单,但也最难学的秘诀.不经过训练,人很难意识到时间复利的威力. 仙剑奇侠传的「十里坡剑神」和金庸群侠传的「十级野球拳」,就是简单的事情持之以恒反复做,最后就 ...

  4. NC16692 [NOIP2001]求先序排列

    NC16692 [NOIP2001]求先序排列 题目 题目描述 给出一棵二叉树的中序与后序排列.求出它的先序排列.(约定树结点用不同的大写字母表示,长度 ≤ 8). 输入描述 2行,均为大写字母组成的 ...

  5. API概述,使用步骤和Scanner概述及其API文档的使用

    API概述 API(Application Programming Interface),应用程序编程接口.Java API是一本程序员的 字典 ,是JDK中提供给 我们使用的类的说明文档.这些类将底 ...

  6. Ubuntu出现视频无法正常播放的问题

    原因是没有安装相关的解码包,参考这个方法: ubuntu下B站(bilibili)视频无法播放 一条命令解决 sudo apt install ubuntu-restricted-extras 要是有 ...

  7. Pytorch 中 tensor的维度拼接

    torch.stack() 和 torch.cat() 都可以按照指定的维度进行拼接,但是两者也有区别,torch.satck() 是增加新的维度进行堆叠,即其维度拼接后会增加一个维度:而torch. ...

  8. shell脚本函数及数组

    函数介绍: 函数function是由若干条shell命令组成的语句块,实现代码重用和模块话编程. 它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部 ...

  9. java------常见的进制、不同进制在代码中的表现形式、进制之间的转化、分辨率、三原色、计算机的存储规则

    常见的进制: 常见的进制:二进制.八进制.十进制.十六进制 不同进制在代码中的表现形式: 进制之间的转化: 二进制转十进制: 普通方法: 快捷方法: 八进制转十进制: 十六进制转十进制: 总结: 分辨 ...

  10. DQL条件查询模糊查询和约束概述

    模糊查询 -- 查询姓马的有哪些? like SELECT * FROM student where name LIKE '马%'; -- 查询姓名第二个字是化的人 SELECT * FROM stu ...