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的性能可以提升。

时间: 2024-11-03 21:10:52

postgresql----Btree索引的相关文章

浅谈PostgreSQL的索引

1. 索引的特性 1.1 加快条件的检索的特性 当表数据量越来越大时查询速度会下降,在表的条件字段上使用索引,快速定位到可能满足条件的记录,不需要遍历所有记录. create table t(id int, info text); insert into t select generate_series(1,10000),'lottu'||generate_series(1,10000); create table t1 as select * from t; create table t2 a

PostgreSQL创建索引并避免写数据锁定(并发的索引)

关于并发建立索引:http://58.58.27.50:8079/doc/html/9.3.1_zh/sql-createindex.html 写这篇blog源自一个帅哥在建索引发生了表锁的问题.先介绍一下Postgresql的建索引语法: Version:9.1 CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ name ] ON table [ USING method ]     ( { column | ( expression ) } [ COLLA

(转)浅谈PostgreSQL的索引

1. 索引的特性 1.1 加快条件的检索的特性 当表数据量越来越大时查询速度会下降,在表的条件字段上使用索引,快速定位到可能满足条件的记录,不需要遍历所有记录. create table t(id int, info text); insert into t select generate_series(1,10000),'lottu'||generate_series(1,10000); create table t1 as select * from t; create table t2 a

索引的分类--B-Tree索引和Hash索引

索引是存储引擎用来快速查找记录的一种数据结构,按照实现的方式有不同的种类,想B-Tree索引,hash索引,空间数据索引和全文索引等.下面主要说一下B-Tree索引和Hash索引.人们在谈论索引的时候如果没有特别说明,一般指的是B-Tree索引.B-Tree索引是使用B-Tree数据结构来存储索引的.B-Tree通常意味着所有的值是按照顺序存储的.B-Tree树有如下几个特征:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点,则至少有两棵子树:⑶除根结点之外的所有非终端结点至少有[m/2]

【Bitmap Index】B-Tree索引与Bitmap位图索引的锁代价比较研究

通过以下实验,来验证Bitmap位图索引较之普通的B-Tree索引锁的“高昂代价”.位图索引会带来“位图段级锁”,实际使用过程一定要充分了解不同索引带来的锁代价情况. 1.为比较区别,创建两种索引类型的测试表1)在表t_bitmap上创建位图索引[email protected]> create table t_bitmap (id number(10), name varchar2(10),sex varchar2(1)); Table created. [email protected]>

B-Tree索引在sqlserver和mysql中的应用

在谈论数据库性能优化的时候,通常都会提到“索引”,但很多人其实并没有真正理解索引,也没有搞清楚索引为什么就能加快检索速度,以至于在实践中并不能很好的应用索引.事实上,索引是一种廉价而且十分有效的优化手段,设计优良的索引对查询性能提升确实能起到立竿见影的效果. 相信很多读者,都了解和使用过索引,可能也看过或者听过”新华字典“.”图书馆“之类比较通俗描述,但是对索引的存储结构和本质任然还比较迷茫. 有数据结构和算法基础的读者,应该都学过或者写过“顺序查找,二分查找(折半)查找,二叉树查找”这几种很经

Hash索引和BTree索引

索引是帮助mysql获取数据的数据结构. 最常见的索引是Btree索引和Hash索引. 不同的引擎对于索引有不同的支持:Innodb和MyISAM默认的索引是Btree索引:而Mermory默认的索引是Hash索引. Hash索引 所谓Hash索引,当我们要给某张表某列添加索引时,将这张表的这一列进行哈希算法计算,得到哈希值.排序在哈希数组上.所以Hash索引能够一次定位.其效率非常高,而Btree索引须要经过多次的磁盘IO.可是innodb和myisam之所以没有採用它,是由于它存在着好多缺点

MySQL的btree索引和hash索引&amp;聚集索引

1,BTREE是多叉树,多路径搜索树.有N棵子树的节点它包含N-1个关键字,例如,有3个子树的非叶子节点,那么就有2个关键字,每个关键字不保存数据,只用来存储索引(在索引存储数据时,将索引指向关键字的值也存储进来.最终实现key = &get; value结构).所有的数据最终都要落在叶子节点,所有的叶子节点包括关键字信息以及指向这些关键字的指针,而且叶子节点是根据关键字大小.顺序链接的.所有的叶子节点都必须有个链表指针把数据串起来.所以,所有非叶子节点可以看成索引部分,包括子树中最大值或最小值

MySQL的btree索引和hash索引的区别

Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引. 可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢?任何事物都是有两面性的,Hash 索引也一样,虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以

0103MySQL中的B-tree索引 USINGWHERE和USING INDEX同时出现

转自博客http://www.amogoo.com/article/4 前提1,为了与时俱进,文中数据库环境为MySQL5.6版本2,为了通用,更为了避免造数据的痛苦,文中所涉及表.数据,均来自于MySQL官网提供的示例库employees,可通过 https://launchpad.net/test-db/employees-db-1/1.0.6 自行下载. 基本概念Binary search(二分查找法,折半查找法):是一种在有序数组中查找某一特定元素的搜索算法.搜素过程从数组的中间元素开始