数据准备

--创建基础数据表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. supervisor的安装与使用

    Ubuntu安装使用supervisor 进程管理工具 安装 apt-get install supervisor 查看是否安装成功 pgrep supervisord # 返回进程号则成功 改配置文 ...

  2. 自己实现一个自定义React项目脚手架「ReactCli」

    前言 首先为什么想到自己实现一个React脚手架呢?是因为之前刚接触create-react-app时,觉得不太灵活.虽然文件目录很清晰,但是还是觉得不如VueCLI的可以自定义配置更加灵活.当然Re ...

  3. 一篇文章带你深入浅出Vuex

    在写Vuex之前,我们先用一个简单的例子来实现一个小demo 大家都知道Vue的父传子用在很多场景,比如像这样: 父组件: <template> <div id="app& ...

  4. 机械硬盘和ssd固态硬盘的原理对比分析

    固态硬盘和机械硬盘的区别 机械硬盘 磁头是不是直接和盘片接触的呢 磁盘中有几个盘片 机械硬盘的工作原理 固态硬盘的寻址方式 SMR叠瓦式真的比PMR优秀吗 固态硬盘 主控芯片 闪存颗粒 缓存单元 固态 ...

  5. Redis开机自启

    添加开机启动服务 vi /etc/systemd/system/redis.service 在redis.service中输入以下内容 ps:ExecStart配置成自己的路径 [Unit] Desc ...

  6. jvm jni 及 pvm pybind11 大批量数据传输及优化

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  7. .Net 应用考虑x64生成

    在x86架构下使用32位应用程序,理论上32位能够分配4G的大小空间,但实际上默认 .NET Framework 可以创建一个不超过 2 GB 的对象,在实际使用过程中可能使用到1.5G的样子就会报内 ...

  8. VS code 远程连接服务器步骤

    ①安装VS code,并连接远程服务器(本地也需要有ssh).参考 ②免密钥登录设置,参考 具体步骤:WIN+R -->cmd, 输入ssh-keygen,然后一直Enter,最终生成公钥和私钥 ...

  9. 2022-07-21 第四组 java之继承

    目录 一.继承 1.概念 2.语法 3.父类成员访问 3.1 子类访问父类的成员变量 3.1.1 子类和父类中不存在同名的成员变量 3.1.2 子类和父类中不存在同名的成员变量 3.2 子类中访问父类 ...

  10. 常用的函数式接口_Predicate接口和常用的函数式借楼_Predicate_默认方法and

    package com.yang.Test.PredicateStudy; import java.util.function.Predicate; /** * java.util.function. ...