PostgreSQL 分页, offset, 返回顺序, 扫描方法原理(seqscan, index scan, index only scan, bitmap scan, parallel xx scan),游标

简介: PostgreSQL 分页, offset, 返回顺序, 扫描方法原理(seqscan, index scan, index only scan, bitmap scan, parallel xx scan),游标

背景

一个这样的问题:

为什么select x from tbl offset x limit x;

两次查询连续的OFFSET,会有重复数据呢?

select ctid,* from tbl where ... offset 0 limit 10;  
select ctid,* from tbl where ... offset 10 limit 10;  

为什么多数时候offset会推荐用order by?

不使用ORDER BY的话,返回顺序到底和什么有关?

答案是:

数据库的扫描方法。

数据库扫描方法,具体的原理可以到如下文档中找到PDF,PDF内有详细的扫描方法图文介绍。

《阿里云 PostgreSQL 产品生态;案例、开发管理实践、原理、学习资料、视频;PG天天象上沙龙记录 - 珍藏级》

扫描方法

1、全表扫描, seqscan

从第一个数据块开始扫描,返回复合条件的记录。

2、并发全表扫描, concurrently seqscan

如果有多个会话,对同一张表进行全表扫描时,后发起的会话会与前面正在扫描的会话进行BLOCK对齐步调,也就是说,后面发起的会话,可能是从表的中间开始扫的,扫描到末尾再转回去,避免多会话同时对一个表全表扫描时的IO浪费。

例如会话1已经扫到了第99个数据块,会话2刚发起这个表的全表扫描,则会从第99个数据块开始扫描,扫完在到第一个数据块扫,一直扫到第98个数据块。

3、索引扫描, index scan

按索引顺序扫描,并回表。

4、索引ONLY扫描, index only scan

按索引顺序扫描,根据VM文件的BIT位判断是否需要回表扫描。

5、位图扫描, bitmap scan

按索引取得的BLOCKID排序,然后根据BLOCKID顺序回表扫描,然后再根据条件过滤掉不符合条件的记录。

这种扫描方法,主要解决了离散数据(索引字段的逻辑顺序与记录的实际存储顺序非常离散的情况),需要大量离散回表扫描的情况。

6、并行扫描, parallel xx scan

并行的全表、索引、索引ONLY、位图扫。首先会FORK出若干个WORKER,每个WORKER负责一部分数据块,一起扫描,WORKER的结果(FILTER后的)发给下一个GATER WORKER节点。

7、hash join

哈希JOIN,

8、nest loop join

嵌套循环

9、merge join

合并JOIN(排序JOIN)。

更多扫描方法,请参考PG代码。

扫描方法决定了数据返回顺序

根据上面的这些扫描方法,我们可以知道一条QUERY下去,数据的返回顺序是怎么样的。

select * from tbl where xxx offset 10 limit 100;  

1、如果是全表扫描,那么返回顺序就是数据的物理存放顺序,然后偏移10条有效记录,取下100条有效记录。

2、如果是索引扫描,则是依据索引的顺序进行扫描,然后偏移10条有效记录,取下100条有效记录。

不再赘述。

保证绝对的连续

如何保证第一次请求,第二次请求,第三次请求,。。。每一次偏移(offset)固定值,返回的结果是完全有序,无空洞的。

1、使用rr隔离级别(repeatable read),并且按PK(唯一值字段、字段组合)排序,OFFSET

使用rr级别,保证一个事务中的每次发起的SQL读请求是绝对视角一致的。

使用唯一字段或字段组合排序,可以保证每次的结果排序是绝对一致的。加速每次偏移的数据一样,所以可以保证数据返回是绝对连续的。

select * from tbl where xx order by a,b offset x limit xx;  

2、使用游标

使用游标,可以保证视角一致,数据绝对一致。

postgres=# \h declare  
Command:     DECLARE  
Description: define a cursor  
Syntax:  
DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]  
    CURSOR [ { WITH | WITHOUT } HOLD ] FOR query  
begin;  
declare a cursor for select * from tbl where xx;  
fetch x from a;  
... 每一次请求,游标向前移动    
end;  

参考

《PostgreSQL 数据离散性 与 索引扫描性能(btree & bitmap index scan)》

《PostgreSQL 11 preview - 分页内核层优化 - 索引扫描offset优化(使用vm文件skip heap scan)》

《PostgreSQL 范围过滤 + 其他字段排序OFFSET LIMIT(多字段区间过滤)的优化与加速》

《PostgreSQL Oracle 兼容性之 - TZ_OFFSET》

《PostgreSQL 索引扫描offset内核优化 - case》

《PostgreSQL 数据访问 offset 的质变 case》

《论count与offset使用不当的罪名 和 分页的优化》

《PostgreSQL offset 原理,及使用注意事项》

《妙用explain Plan Rows快速估算行 - 分页数估算》

《分页优化 - order by limit x offset y performance tuning》

《分页优化, add max_tag column speedup Query in max match enviroment》

《PostgreSQL's Cursor USAGE with SQL MODE - 分页优化》

PostgreSQL 许愿链接

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.

9.9元购买3个月阿里云RDS PostgreSQL实例

PostgreSQL 解决方案集合

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
9月前
|
关系型数据库 测试技术 Linux
PostgreSQL配置文件修改及启用方法
总的来说,修改和启用PostgreSQL的配置文件是一个直接而简单的过程。只需要找到配置文件,修改你想要改变的选项,然后重启服务器即可。但是,你需要注意的是,不正确的配置可能会导致服务器性能下降,甚至导致服务器无法启动。因此,在修改配置文件之前,你应该充分理解每个选项的含义和影响,如果可能的话,你应该在测试环境中先进行试验。
724 72
|
SQL 关系型数据库 Linux
在CentOS 6上安装和使用PostgreSQL的方法
在CentOS 6上安装和使用PostgreSQL的方法
286 2
|
Ubuntu 关系型数据库 数据库
在Ubuntu 18.04上安装和使用PostgreSQL的方法
在Ubuntu 18.04上安装和使用PostgreSQL的方法
332 1
|
Ubuntu 关系型数据库 Linux
在Ubuntu 14.04上安装和使用PostgreSQL的方法
在Ubuntu 14.04上安装和使用PostgreSQL的方法
208 1
|
关系型数据库 Linux 数据库
在CentOS 7上安装和使用PostgreSQL的方法
在CentOS 7上安装和使用PostgreSQL的方法
1962 0
|
SQL 关系型数据库 MySQL
postgresql |数据库 |数据库的常用备份和恢复方法总结
postgresql |数据库 |数据库的常用备份和恢复方法总结
499 0
|
SQL JSON 关系型数据库
PostgreSQL安装、配置及简单使用方法
一、PostgreSQL简介 1、什么是PostgreSQL PostgreSQL数据库是目前功能最强大的开源数据库,支持丰富的数据类型(如JSON何JSONB类型,数组类型)和自定义类型。而且它提供了丰富的接口,可以很容易地扩展它的功能,如可以在GiST框架下实现自己的索引类型等,它还支持使用C语言写自定义函数、触发器,也支持使用流行的语言写自定义函数,比如其中的PL/Perl提供了使用Perl语言写自定义函数的功能,当然还有PL/Python、PL/Tcl,等等。 2、PostgreSQL数据库的优势 PostgreSQL数据库是目前功能最强大的开源数据库,它是最接近工业标准SQL
2110 0
|
SQL NoSQL 关系型数据库
PostgreSQL 准确且快速的数据对比方法
作为一款强大而广受欢迎的开源关系型数据库管理系统,PostgreSQL 在数据库领域拥有显著的市场份额。其出色的可扩展性、稳定性使其成为众多企业和项目的首选数据库。而在很多场景下(开发 | 生产环境同步、备份恢复验证、数据迁移、数据合并等),不同环境中的数据库数据可能导致数据的不一致,因此,进行数据库之间的数据对比变得至关重要。
606 0
|
存储 关系型数据库 PostgreSQL
PostgreSQL表扫描方法解析
PostgreSQL表扫描方法解析
340 0
|
存储 NoSQL 关系型数据库
PostgreSQL 12的可拔插存储引擎--表访问方法以及bloackholes案例
PostgreSQL 12的可拔插存储引擎--表访问方法以及bloackholes案例
319 0

相关产品

  • 云原生数据库 PolarDB
  • 推荐镜像

    更多