暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

人大金仓数据库Hint指定扫描方式

原创 数据猿 2023-12-12
425


Hint指定扫描方式

关键字:

Hint、indexscan、bitmapscan、seq scan、人大金仓、KingbaseES

概述

Scan类型的Hint是指明单表扫描时在目标表上使用特定的扫描方法。它只会在普通表、继承表、UNLOGGED表、临时表和系统目录上生效。外部表、表函数、VALUES子句、CTE、视图和子查询不受影响。其括号内的值只能是一个表名。但可以在一个查询中,对其中的多个目标表进行不同方式的干预。具体类型及对应的描述如下:

Hint类型

描述

SeqScan(table)

优先在表上使用顺序扫描

TidScan(table)

优先在表上使用Tid扫描

IndexScan(table[ index...])

优先在表上使用[指定的]索引扫描

IndexOnlyScan(table[ index...])

优先在表上只扫描索引列(Index Only Scan)

Index Only Scan不可用时,可以使用索引扫描

BitmapScan(table[ index...])

优先在表上使用位图扫描

NoSeqScan(table)

优先不在表上使用顺序扫描

NoTidScan(table)

优先不在表上使用Tid扫描

NoIndexScan(table)

优先不在表上使用指定的索引扫描

NoIndexOnlyScan(table)

优先不在表上使用index only scan

NoBitmapScan(table)

优先不在表上使用位图索引

ForceSeqScan(table)

强制在表上使用顺序扫描

ForceTidScan(table)

强制在表上使用Tid扫描

ForceIndexScan(table[ index...])

强制在表上使用指定的索引扫描

ForceIndexOnlyScan(table[ index...])

强制在表上只扫描索引列 (Index Only Scan)

Index Only Scan不可用时,可以使用索引扫描

ForceBitmapScan(table[ index...])

强制在表上使用位图扫描

Scan类型的Hint场景

(1) Seq Scan — — 顺序扫描

按照表的记录的排列顺序从头到尾依次检索扫描,每次扫描要取到所有的记录,这也是最简单的扫表方式,扫描的代价较大。

顺序扫描一般满足以下条件:

① 谓词的列上没有索引

② 查询返回大多数的行

(2) Tid Scan — — Tid扫描(基于行号的快速扫描)

KES的表是堆表,数据按行存储在HEAP PAGE中,在Btree索引中,除了存储字段的value,还会存储对应的ctid(即行号),因此,通过行号是可以快速检索到记录的。

行号的写法是(page_number, item_number),数据块从0开始编号,行号从1开始编号。如果要使用Tid扫描,必须开启参数enable_tidscan,否则就会走全表扫描,会非常慢。

【注】GUC参数enable_tidscan默认是开启的(on)

(3) Index Scan — — 索引扫描

对于给定的查询,先扫描一遍索引,从索引中找到符合要求的记录的位置,再定位到表中具体的Page去取。相当于是两次I/O,先走索引,再走取表记录,不同于全表扫描的是只取所需数据对应的Page,I/O量比较小。

(4) Index Only Scan — — 只扫描索引列

Index Only Scan与Index Scan类似,除了第二步(即“再走取表记录”这一步),它只扫描索引数据结构

选择Index Only Scan有两个先决条件:

① 查询应该只获取索引中的部分列

② 选中表页上的所有元组(记录)都应该是可见的

简单来说,Index Only Scan就是因为建立索引时,所包含的字段集合,囊括了查询语句中的所有字段,故提取出相应的索引后,就不需要再次提取记录了

(5) BitmapScan — — 位图扫描

普通的索引扫描一次只能读一条索引项,那么一个PAGE就有可能被多次访问,而位图扫描会一次性将满足条件的索引项全部取出,并在内存中进行排序,然后根据取出的索引访问表数据。通常是需要合并索引访问结果子集时会用到这种方式

位图扫描的原理是在扫描过程中单个块只使用一次。位图扫描方法利用了索引扫描的优点,而不需要随机I/O,具体实现过程分为以下两个层次:

位图索引扫描:首先从索引数据结构中获取所有索引数据,并创建所有TID的位图(可以认为此位图包含所有页的哈希值——基于page no哈希),每个页面包含该页面中所有偏移量的数组。

位图堆扫描:读取页的位图,然后扫描与存储页和偏移量对应的堆中的数据,最后检查可见性和谓词等,并根据检查结果返回元组。

【小结】上述5种扫描方式的应用场景

当获取的数据分布很大时(比如70%以上),使用Index Scan就没有意义了,因为数据太多了,走索引再走表的代价已经超过了单纯走表的代价了,就不如使用Seq Scan了。

当数据分布较小时(比如1.7%)Index Scan的优势就显露出来了。当然,可能Bitmap Index Scan的性能就更好了(因为相较于Index Scan,它减少了index的重复扫描)。

当数据更少时,用Index Scan可能就更好(索引重复的可能性小,且回避了内存中排序的代价)。

当where条件单一时Bitmap Index Scan可能更适合。

⑤ 对于Index Only Scan,由于不需要扫描表的数据块,只走索引,那么在满足其使用条件的情况下,几乎就是最快的了。


最后修改时间:2023-12-12 15:56:42
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论