一个列要不要建立btree索引,判断条件是其键值分布是否够离散,比如主键、唯一键,可以建立索引。如果这个列有大量重复的值,则建立索引没有意义。

在生产环境中常会碰到键值分布不均匀的列,如表t1有一个名为FLAG的列,有0,1,2三个值,其中值为0的记录占95%,值为1的占3%,2占2%。在FLAG上建立索引,搜索FLAG=1或2可利用到此索引,而搜索FLAG=0 则因有大量的重复值而利用不到此索引。也就是说此索引有95%的内容是无效的,白白浪费了存储等资源。

KingbaseES有种索引,叫Partial Index(局部索引)可以很好的解决以上问题。

1 什么是partial index

局部索引是基于表中部分数据建立的,被索引的部分数据是原数据的一个子集。这个子集数据是基于某些条件可以明确计算出来的。

2 partial index适用场景

对于表中数据分布“不均匀”的场景,比如某些数据占据绝大多数,而其它一些数据只占少量,且要满足查询条件针是对那些小数据量的查询情形。

通过partial index可以排除大量普通数据或业务上“不感兴趣”的数据。

3 partial index的优势

由于其是针对部分数据进行索引,显然同传统b-tree索引相比,其所占磁盘空间将大大缩小。当重建维护这些分区索引时,速度也非常快。

test=# create table t_pindex(id int,name varchar(30));
CREATE TABLE
test=# insert into t_pindex select generate_series(1,2000),'AAA';
INSERT 0 2000
test=# insert into t_pindex select generate_series(2001,2050),'BBB';
INSERT 0 50
test=# create index idx_pindex on t_pindex(name) where name != 'AAA';
CREATE INDEX
test=# create index idx_full on t_pindex(name);
CREATE INDEX
test=# analyze t_pindex; 在本例子中AAA值占比超过95%,所以即使列上有索引也不会使用索引扫描
test=# explain analyze select * from t_pindex where name = 'AAA';
QUERY PLAN
----------------------------------------------------------------------------------------------------------
Seq Scan on t_pindex (cost=0.00..35.62 rows=2000 width=8) (actual time=0.036..18.522 rows=2000 loops=1)
Filter: ((name)::text = 'AAA'::text)
Rows Removed by Filter: 50
Planning Time: 0.266 ms
Execution Time: 35.368 ms
(5 行记录) 局部索引的存储空间比普通索引的存储空间要小。
test=# \di+ idx_full
关联列表
-[ RECORD 1 ]------
架构模式 | public
名称 | idx_full
类型 | 索引
拥有者 | system
数据表 | t_pindex
大小 | 64 kB
描述 | test=# \di+ idx_pindex
关联列表
-[ RECORD 1 ]--------
架构模式 | public
名称 | idx_pindex
类型 | 索引
拥有者 | system
数据表 | t_pindex
大小 | 16 kB
描述 | 使用hint指定查询时使用的索引,可以看出局部索引的查询效率会高于普通的索引。
test=# explain analyze select /*+ indexscan(a idx_pindex) */ * from t_pindex a where name = 'BBB';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Index Scan using idx_pindex on t_pindex a (cost=0.14..13.02 rows=50 width=8) (actual time=0.025..0.392 rows=50 loops=1)
Index Cond: ((name)::text = 'BBB'::text)
Planning Time: 0.084 ms
Execution Time: 0.785 ms
(4 行记录) test=# explain analyze select /*+ indexscan(a idx_full) */ * from t_pindex a where name = 'BBB';
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Index Scan using idx_full on t_pindex a (cost=0.28..9.15 rows=50 width=8) (actual time=0.060..0.668 rows=50 loops=1)
Index Cond: ((name)::text = 'BBB'::text)
Planning Time: 0.154 ms
Execution Time: 1.760 ms
(4 行记录)

最新文章

  1. 重新认识了下Entity Framework
  2. 最终版的Web(Python实现)
  3. 头文件algorithm中的常用函数
  4. httpclient 4.5 get请求
  5. bug检测报告---礼物挑选小工具--飞天小女警
  6. 拖动div简单事例代码
  7. apache commons vfs 文件夹监控
  8. 一个Hibernate小程序
  9. jquery 选择器 的学习,自己慢慢来
  10. jboss-AS目录结构了解(资料摘取)
  11. PowerDesigner中NAME和COMMENT的互相转换,需要执行语句
  12. 没什么技术含量的Remove Before Flight
  13. Java进阶(二十六)公司项目开发知识点回顾
  14. Tomcat中常见线程说明
  15. 大数据学习之Linux基础01
  16. 1.3浅谈Spring(IOC容器的实现)
  17. StringRedisTemplate常用操作
  18. iframe在iphone中滚动条无效
  19. Can't find model 'en'
  20. poj2828 伸展树模拟

热门文章

  1. ansible-playbook批量修改密码
  2. ssh空闲一段时间后自动断网
  3. 面试突击61:说一下MySQL事务隔离级别?
  4. 基于mysql实现group by取各分组最新一条数据
  5. 本地拉取服务器上的项目,SVN 由于目标计算机积极拒绝 无法连接失败
  6. 还在因为部署 Kubernetes 时,无法拉取 k8s.gcr.io/*** 镜像而头疼吗
  7. Math类和函数定义
  8. BufferedWniter_字符缓冲输出流和BufferedReader_字符缓冲输入流
  9. antd vue 折叠面板 v-for 循环点击无效
  10. Python图像处理丨图像腐蚀与图像膨胀