摘要:本文章先描述了常用的索引,并针对B-tree和Psort两种索引具体介绍,下面给出索引的利与弊。除了索引,还介绍了分区、PCK等其他查询提速的手段。最后给出各种索引和调优手段的使用场景。
索引能干什么呢,一言以蔽之:查询加速。常见的索引有下面几种:

B-tree存储结构示意如下:

在数据库里面举个例子,如何创建B-tree索引:
Psort索引数据结构示意如下图所示:

横向对比B-tree、Psort如下:
表达式索引
比如对于查询“select * from test1 where lower(col1) = ‘value’;”可以建立在Lower表达式之上的索引“create index on test1(lower(col1));”,后续对于类似在lower(col1)表达式上的过滤条件,就可以直接使用这个索引加速,对于其他表达式该索引不会对查询生效。但需要注意的是:索引表达式的维护代价较为昂贵,因为在每一个行被插入或更新时都得为它重新计算相应的表达式。
比如创建一个部分索引“create index idx2 on test1(ip) where not (ip > ’10.185.178.100’ and ip < ’10.185.178.200’);”,使用该缩影加速的典型查询是这样“select * from test1 where ip = ’10.185.178.150’”,但是对于查询“select * from test1 where ip = ’10.185.178.50’”就不能使用该索引。部分索引用来减少索引的大小,排除掉查询不感兴趣的数据,同时可以加速索引的检索效率.
(1)只有B-tree索引支持唯一索引;
(2)当一个索引被声明为唯一时,索引中不允许多个表行具有相同的索引值;
(3)空值被视为不相同,一个多列唯一索引将会拒绝在所有索引列上具有相同组合值的表行;
(4)对于主键列会自动创建一个唯一索引;
(5)唯一性检查会影响索引插入性能;
索引的优点如下:
索引的缺点如下:
鉴于索引的使用是一把双刃剑,创建索引要谨慎,只给有需要的列创建,不能过滤大量数据的条件列不要创建索引。除了索引可以优化查询效率,存储层还有没有其他优化手段呢?下面给大家再介绍几种DWS查询提速的手段。
分区是最常用的提速手段之一,而且效果很好,推荐大家结合场景多多使用。
使用分区的注意事项如下:
下面举个例子,分别创建同样数据类型的分区表和非分区表,导入相同的数据640万条,用同样的查询会看到分区剪枝对性能提高了7倍多,准备数据:

分区和非分区查询耗时对比,其中test1是分区表,test2是非分区表,test1的查询scan耗时6ms,test2的查询scan耗时46ms,差距7倍还多:

PCK的本质就是通过排序提升查询过滤的效率,创建表时指定PCK列,该列上的数据会局部排序,有序的数据带来更好的数据聚簇性,每个数据块的min/max等稀疏索引就能更好的发挥作用,粗过滤掉大量的数据,提升IO效率,默认情况下420万行数据局部排序。
注意事项如下:
举个例子,对于查询select * from tab where col > 65,如果不使用PCK,很可能一个CU都无法过滤掉,但如果使用了PCK,下图所示的5个CU就能过滤掉一半还多,提升查询性能至少50%:

再用上面分区的那组数据横向对比PCK的性能表现:
(1)列存表,非分区,无PCK,scan耗时46ms

(2)列存表,非分区,有PCK,scan耗时1.7ms

(3)列存表,有PCK,再创建btree索引,scan耗时0.1ms

PCK结合索引,可以将类似这种点查的性能提升100倍以上。
列存表数据从文件读出来,到反馈给执行层,中间会智能识别自动多层过滤,对用户完全透明,如下图所示:


本文分享自华为云社区《DWS 索引的正确“打开姿势”》,原文作者:hoholy 。
原文:https://www.cnblogs.com/huaweiyun/p/14713517.html