本文分享自华为云社区《》,作者:我的橘子呢 。
为实现不同的功能,GaussDB(DWS)提供了不同的数据对象类型,包括索引、行存表、列存表及其辅助表等。这些数据对象在特定的条件下实现不同的功能,为数据库的快速高效提供了保证,本文对部分数据对象进行介绍。
1.索引(index)索引是关系型数据库中对某一列或者多个列的值进行预排序的数据结构。如果数据库的记录非常多,通过建立索引可以获得非常快的查询速度,当对某一列建立索引之后,通过该列进行相关查询时数据库系统就不必扫描整个表,而是直接通过索引定位到符合条件的记录,在一定程度上能够大幅提升查询得速度。
假如需要执行如下的语句进行查询:
SELECT name FROM test_1 WHERE number =10;
一般情况下数据库需要对每一行进行遍历查询,直到找到所有满足条件number=10的元组信息。当数据库的记录很多,而满足where条件的记录又很少时,顺序扫描的性能就会很差。这时如果在表test_1的number属性上建立索引,用于快速定位需要匹配的元组信息,数据库只需要根据索引的数据结构进行搜索,由于常用的索引结构有B-Tree、Hash、GiSt、GIN等,这些索引结构的查询都是快速高效的,因此可以在少数几步内完成查询,大大提高了查询效率。
对表test_1的number属性建立索引语句如下:
CREATE INDEX numberIndex ON test_1(number);
由于GaussDB里的所有索引都是“从属索引”,索引在物理文件上与原来的表文件分离,执行上述创建索引语句后,系统会生成relname为numberIndex的索引类型。表和索引都是数据库对象,在pg_class里会有该索引的记录,有与之相对应的oid,同时在pg_index表里会记录索引及其对应主表的信息。对应属性信息如图1所示。
图1 pg_index部分属性
2.toast表toast(The Oversized-Atttibute Storage Techhnique)即超尺寸字段存储技巧,是数据库提供的一种存储大数据的机制。只有一些具有变长表现形式的数据类型才会支持toast,比如TEXT类型。由于在GaussDB(DWS)的行存储方式中,一条数据的所有列组合在一起称之为一个tuple,多个tuple组成一个page。page是数据在文件存储中的基本单位,其大小是固定的且只能在编译器指定,之后无法修改,默认发大小为8KB,当某行数据很大超过page的大小时,数据库系统就会启动toast,对数据进行压缩和切片。实际数据以行外存储的形式存储在另外一张表中,这张表就是toast表。
当一张表的任何一个属性是可以toast的,则这张表会有一张关联的toast表,在pg_class里表的reltoastrelid属性里记录了该toast表的oid,如果没有关联的toast表,reltoastrelid=0。那么如何判断一张表的属性是否是可以toast的呢?我们可以在表的Storage选项中查看对应属性的存储策略。有以下四种不同的存储策略:
- PLAIN:避免压缩或者行外存储;此外,它禁止为变长类型使用单字节的头。 这只对那些不能TOAST的数据类型的列才有可能。
- EXTENDED:允许压缩和行外存储。 这是大多数TOAST数据类型的缺省策略。首先会尝试对数据进行压缩, 如果行仍然太大,则进行行外存储。
- EXTERNAL:允许行外存储,但是不许压缩。 使用EXTERNAL,将使那些数据类型为text和bytea的字段上的子字符串操作更快 (代价是增加了存储空间),因为这些操作是经过优化的:如果行外数据没有压缩,那么它们只会获取需要的部分。
- MAIN:允许压缩,但不允许行外存储。 实际上,在这样的字段上仍然会进行行外存储, 但只是作为没有办法把数据行变得更小以使之足以放置在一个页面中的最后选择。
假如创建表语句如下:
CREATE TABLE test_t(id int,description text);
创建了一张test_t表,该表有id和description两个属性,分别属于int和text类型,查看该表的属性对应的Storage策略:
图2 test_t表相关信息
我们可以看出description属性的Storage策略为EXTENDED,是可以toast的,系统会为test_t表创建一张关联的toast表。
图3 test_t表对应toast表
通过查询pg_class,可以的看到表test_t关联的toast表的oid为52579,进一步以此oid为条件在pg_class里就会得到toast表的相关信息。