postgresql----Btree索引
当表数据量越来越大时查询速度会下降,像课本目录一样,在表的条件字段上创建索引,查询时能够快速定位感兴趣的数据所在的位置。索引的好处主要有加速带条件的查询,删除,更新,加速JOIN操作,加速外键约束更新和删除的操作等,但是索引也不是只有好处没有坏处,创建索引时会锁表,不仅将数据写入表中,还要创建索引,因此会在一定程度上影响写的性能。
Btree索引适合处理能够按顺序存储的数据的=,<,>,<=,>=,以及等效这些操作符的其他操作如BETWEEN,IN以及IS NULL和以字符串开头的模糊查询。Btree索引要想起作用where条件必须包含第一个索引列。
测试表:
test=# create table tbl_index(a bigint,b timestamp without time zone,c varchar(12));
CREATE TABLE
test=# insert into tbl_index (a,b,c) select generate_series(1,3000000),clock_timestamp()::timestamp(0) without time zone,'got u';
INSERT 0 3000000
test=# \timing
Timing is on.
示例1.创建索引前查询
test=# select * from tbl_index where a=3000000;
a | b | c
---------+---------------------+-------
3000000 | 2016-06-29 14:54:00 | got u
(1 row) Time: 303.729 ms
创建索引:
test=# create index idx_tbl_index_a on tbl_index using btree(a);
CREATE INDEX
Time: 3743.555 ms
示例2.创建索引后查询
test=# select * from tbl_index where a=3000000;
a | b | c
---------+---------------------+-------
3000000 | 2016-06-29 14:54:00 | got u
(1 row) Time: 2.316 ms
删除索引
test=# drop index idx_tbl_index_a ;
DROP INDEX
创建组合索引
test=# create index idx_tbl_index_a_b on tbl_index using btree(a,b);
CREATE INDEX
Time: 2987.971 ms
使用explain命令输出查询计划,并使用analyze参数实际执行SQL语句。
示例3.按字段a查询
test=# explain analyze select * from tbl_index where a=3000000;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
Index Scan using idx_tbl_index_a_b on tbl_index (cost=0.43..8.45 rows=1 width=22) (actual time=0.026..0.027 rows=1 loops=1)
Index Cond: (a = 3000000)
Planning time: 0.127 ms
Execution time: 0.073 ms
(4 rows) Time: 1.435 ms
示例4.按字段b查询
test=# explain analyze select * from tbl_index where b='2016-06-29 14:54:00';
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
Gather (cost=1000.00..38495.00 rows=171000 width=22) (actual time=306.211..514.992 rows=172824 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on tbl_index (cost=0.00..21107.50 rows=71250 width=22) (actual time=284.671..296.463 rows=57608 loops=3)
Filter: (b = '2016-06-29 14:54:00'::timestamp without time zone)
Rows Removed by Filter: 942392
Planning time: 0.191 ms
Execution time: 524.130 ms
(8 rows) Time: 525.623 ms
示例5.组合字段查询 a and b
test=# explain analyze select * from tbl_index where a=3000000 and b='2016-06-29 14:54:00';
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
Index Scan using idx_tbl_index_a_b on tbl_index (cost=0.43..8.45 rows=1 width=22) (actual time=0.031..0.033 rows=1 loops=1)
Index Cond: ((a = 3000000) AND (b = '2016-06-29 14:54:00'::timestamp without time zone))
Planning time: 0.169 ms
Execution time: 0.075 ms
(4 rows) Time: 1.173 ms
示例6.组合字段查询 a or b
test=# explain analyze select * from tbl_index where a=3000000 or b='2016-06-29 14:54:00';
QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------
-------------
Bitmap Heap Scan on tbl_index (cost=34034.37..41369.38 rows=171001 width=22) (actual time=130.579..145.787 rows=172824 loops=1)
Recheck Cond: ((a = 3000000) OR (b = '2016-06-29 14:54:00'::timestamp without time zone))
Heap Blocks: exact=276
-> BitmapOr (cost=34034.37..34034.37 rows=171001 width=0) (actual time=130.480..130.480 rows=0 loops=1)
-> Bitmap Index Scan on idx_tbl_index_a_b (cost=0.00..4.44 rows=1 width=0) (actual time=0.026..0.026 rows=1 loops=1)
Index Cond: (a = 3000000)
-> Bitmap Index Scan on idx_tbl_index_a_b (cost=0.00..33944.43 rows=171000 width=0) (actual time=130.452..130.452 rows=172
824 loops=1)
Index Cond: (b = '2016-06-29 14:54:00'::timestamp without time zone)
Planning time: 0.215 ms
Execution time: 153.074 ms
(10 rows) Time: 154.065 ms
表中的索引实际是btree(a,b),从以上示例中可以看出,只有where条件包含索引的第一个字段,查询才会进行索引扫描,否则将进行全表扫描。示例5和示例6比较可知,组合索引字段间使用and和or(测试例使用pg9.6,记得低版本pg组合索引使用or查询会进行全表扫描,这个不知道是不是记错了)虽然都是索引扫描,但是and组合要比or组合查询速度更快。
删除组合索引,然后分别在a和b字段上创建索引
test=# drop index idx_tbl_index_a_b ;
DROP INDEX
Time: 36.017 ms
test=# create index idx_tbl_index_a on tbl_index using btree (a);
CREATE INDEX
Time: 2277.276 ms
test=# create index idx_tbl_index_b on tbl_index using btree (b);
CREATE INDEX
Time: 2278.055 ms
分别使用a and b和a or b进行查询
test=# explain analyze select * from tbl_index where a=3000000 and b='2016-06-29 14:54:00';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
Index Scan using idx_tbl_index_a on tbl_index (cost=0.43..8.45 rows=1 width=22) (actual time=0.099..0.100 rows=1 loops=1)
Index Cond: (a = 3000000)
Filter: (b = '2016-06-29 14:54:00'::timestamp without time zone)
Planning time: 0.779 ms
Execution time: 0.137 ms
(5 rows) Time: 2.154 ms
test=# explain analyze select * from tbl_index where a=3000000 or b='2016-06-29 14:54:00';
QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------
--------
Bitmap Heap Scan on tbl_index (cost=1840.87..9175.88 rows=171001 width=22) (actual time=29.026..48.537 rows=172824 loops=1)
Recheck Cond: ((a = 3000000) OR (b = '2016-06-29 14:54:00'::timestamp without time zone))
Heap Blocks: exact=276
-> BitmapOr (cost=1840.87..1840.87 rows=171001 width=0) (actual time=28.968..28.968 rows=0 loops=1)
-> Bitmap Index Scan on idx_tbl_index_a (cost=0.00..4.44 rows=1 width=0) (actual time=0.022..0.022 rows=1 loops=1)
Index Cond: (a = 3000000)
-> Bitmap Index Scan on idx_tbl_index_b (cost=0.00..1750.93 rows=171000 width=0) (actual time=28.943..28.943 rows=172824 l
oops=1)
Index Cond: (b = '2016-06-29 14:54:00'::timestamp without time zone)
Planning time: 0.142 ms
Execution time: 57.446 ms
(10 rows) Time: 58.151 ms
结果显示分别在a和b字段上创建索引与在(a,b)组合字段上创建索引相比,and查询性能下降,但是or的性能可以提升。
PS:主键和唯一键会自动创建Btree索引,无需另外单独再为主键和唯一键创建索引。
postgresql----Btree索引的更多相关文章
- PostgreSQL内核分析——BTree索引
文中附图参考至<PostgreSQL数据库内核分析> (一)概念描述 B+树是一种索引数据结构,其一个特征在于非叶子节点用于描述索引,而叶子节点指向具体的数据存储位置.在PostgreSQ ...
- PostGreSQL不同索引类型(btree & hash)的性能问题
在关系型数据库调优中,查询语句涉及到的索引类型是不得不考虑的一个问题.不同的类型的索引可能会适用不同类型的业务场景.这里我们所说的索引类型指的是访问方法(Access Method),至于从其他维度区 ...
- 浅谈PostgreSQL的索引
1. 索引的特性 1.1 加快条件的检索的特性 当表数据量越来越大时查询速度会下降,在表的条件字段上使用索引,快速定位到可能满足条件的记录,不需要遍历所有记录. create table t(id i ...
- mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)
没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...
- (转)浅谈PostgreSQL的索引
1. 索引的特性 1.1 加快条件的检索的特性 当表数据量越来越大时查询速度会下降,在表的条件字段上使用索引,快速定位到可能满足条件的记录,不需要遍历所有记录. create table t(id i ...
- 0103MySQL中的B-tree索引 USINGWHERE和USING INDEX同时出现
转自博客http://www.amogoo.com/article/4 前提1,为了与时俱进,文中数据库环境为MySQL5.6版本2,为了通用,更为了避免造数据的痛苦,文中所涉及表.数据,均来自于My ...
- Btree 索引
Btree 索引 索引是帮助数据库高效获取数据的一种数据结构,通过提取句子主干,就可以得到索引的本质. m-way查找树 如果想了解Btree,需要首先了解m-way数据结构. m-way查找树是是一 ...
- B-Tree索引在sqlserver和mysql中的应用
在谈论数据库性能优化的时候,通常都会提到“索引”,但很多人其实并没有真正理解索引,也没有搞清楚索引为什么就能加快检索速度,以至于在实践中并不能很好的应用索引.事实上,索引是一种廉价而且十分有效的优化手 ...
- MySQL的btree索引和hash索引的区别
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...
- MySQL索引类型 btree索引和hash索引的区别
来源一 Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 ...
随机推荐
- 初涉RxAndroid结合Glide实现多图片载入操作
转载请注明出处:王亟亟的大牛之路 本来周末就想发了然后各种拖拉就没有然后了,那么就今天早上写吧,废话不多開始正题 什么是RxJava或者RxAndroid我就不多废话了,理论知识一大堆人给我们做好了. ...
- 在PADS中,大面积覆铜有3个重要概念
- 蔡勒(Zeller)公式
来源好搜百科:http://baike.haosou.com/doc/1048888-1109421.html 蔡勒(Zeller)公式,是一个计算星期的公式,随便给一个日期,就能用这个公式推算出是星 ...
- MyEclipse 对项目进行build path无效
今天发现昨天从svn下载下来的项目在MyEclipse中无法build path .提示no actions available 在网上找了下,是由于.projects文件的问题,须要在当中的natu ...
- 第四章 Spring.Net 如何管理您的类___让对象了解自己的容器
我们在开发中,经常需要让对象了解自己所在的容器的信息,例如,有时我们需要让对象知道,对象所在容器的引用是什么,或者是对象在容器中的名称是什么 .Spring.Net 中提供了两个接口,我们使用这两个接 ...
- oracle的常用函数 instr() 和substr()函数
from:http://1055592535.iteye.com/blog/1676235 在Oracle中 可以使用instr函数对某个字符串进行判断,判断其是否含有指定的字符. 在一个字符串中查找 ...
- SQLServer------插入数据时出现IDENTITY_INSERT错误
详细错误信息: 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'Student' 中的标识列插入显式值. 原因: 表中存在某个字段是自动增长的标识符 解决方法: set IDENT ...
- Java精选笔记_Java入门
Java概述 什么是Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言 JavaSE标准版 是为开发普通桌面和商务应用程序提供的解决方案 JavaEE企业版 是为开发企业级应用程序提供的解 ...
- swift - 之 UICollectionView的用法/自定义流布局
具体代码如下: 1.声明 var hCollectionView:UICollectionView? var layout:UICollectionViewFlowLayout? let course ...
- swift - UIStepper的用法
在网上查看学习资料的时候,看到有这个控件,所以就自己写了下,感觉在某些特定的地方用的还是挺方便的! 不过,个人感觉,局限性太大! 1.初始化(创建个label是为了让大家看到具体的数值) let st ...