PostgreSQL中的Btree索引有什么作用
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,本篇内容主要讲解"PostgreSQL中的Btree索引有什么作用",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"PostgreSQL中的Btree索引有什
千家信息网最后更新 2025年02月01日PostgreSQL中的Btree索引有什么作用
本篇内容主要讲解"PostgreSQL中的Btree索引有什么作用",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"PostgreSQL中的Btree索引有什么作用"吧!
结构
Btree是常见的数据结构,有以下特性:
1.Btree是平衡树,以root节点为分界,左右两边的中间节点数目一样,也就是说查询任意一个值,时间都是一样的
2.Btree有多个分支,每个page(8KB)可以有数百个TIDs,也就是说Btree只需要不多的几个层次就可以支持行数巨大的表
3.索引中的数据Page之间和Page内部都是有序的,相同层次的Page通过双向链表彼此连接
NULLs
PostgreSQL在创建索引时会存储NULLs,因此条件为IS NULL和IS NOT NULL时可以支持索引扫描.
testdb=# insert into t_null select x,'c1'||x from generate_series(1,10000) as x;INSERT 0 10000testdb=# insert into t_null values(null,null);INSERT 0 1testdb=# testdb=# create index idx_t_null_id on t_null(id);CREATE INDEXtestdb=# analyze t_null;ANALYZEtestdb=# testdb=# explain verbose select * from t_null where id is null; QUERY PLAN ------------------------------------------------------------------------------------ Index Scan using idx_t_null_id on public.t_null (cost=0.29..8.30 rows=1 width=10) Output: id, c1 Index Cond: (t_null.id IS NULL)(3 rows)testdb=# explain verbose select * from t_null where id is not null; QUERY PLAN -------------------------------------------------------------------- Seq Scan on public.t_null (cost=0.00..155.01 rows=10000 width=10) Output: id, c1 Filter: (t_null.id IS NOT NULL)(3 rows)testdb=# testdb=# truncate t_null;TRUNCATE TABLEtestdb=# insert into t_null select null,null from generate_series(1,10000);INSERT 0 10000testdb=# insert into t_null values(1,'1');INSERT 0 1testdb=# analyze t_null;ANALYZEtestdb=# testdb=# explain verbose select * from t_null where id is null; QUERY PLAN ------------------------------------------------------------------- Seq Scan on public.t_null (cost=0.00..135.01 rows=10000 width=6) Output: id, c1 Filter: (t_null.id IS NULL)(3 rows)testdb=# explain verbose select * from t_null where id is not null; QUERY PLAN ----------------------------------------------------------------------------------- Index Scan using idx_t_null_id on public.t_null (cost=0.29..8.30 rows=1 width=6) Output: id, c1 Index Cond: (t_null.id IS NOT NULL)(3 rows)testdb=#
NULLs可以保存在Index的最前面,也可以保存在最后面,可通过FIRST/LAST关键字指定,这对排序会有所影响.
testdb=# create table t_null_sort(id int,c1 varchar(20));CREATE TABLEtestdb=# testdb=# insert into t_null_sort select x,'c1'||x from generate_series(1,10000) as x;INSERT 0 10000testdb=# insert into t_null_sort values(null,null);INSERT 0 1testdb=# testdb=# create index idx_t_null_id_first on t_null_sort(id nulls first);CREATE INDEXtestdb=# create index idx_t_null_id_last on t_null_sort(id nulls last);CREATE INDEXtestdb=# testdb=# analyze t_null_sort;ANALYZEtestdb=# testdb=# explain verbose select * from t_null_sort order by id nulls first; QUERY PLAN ----------------------------------------------------------------------------------------------------- Index Scan using idx_t_null_id_first on public.t_null_sort (cost=0.29..328.30 rows=10001 width=10) Output: id, c1(2 rows)testdb=# explain verbose select * from t_null_sort order by id nulls last; QUERY PLAN ---------------------------------------------------------------------------------------------------- Index Scan using idx_t_null_id_last on public.t_null_sort (cost=0.29..328.30 rows=10001 width=10) Output: id, c1(2 rows)testdb=# testdb=#
INCLUDE
创建索引时,通过使用INCLUDE可以把非索引字段加入到该索引中,在通过索引扫描时如投影列只包含索引列和INCLUDE列,那么可以通过INDEX ONLY SCAN扫描Fetch数据.
testdb=# create table t_include(id int,c1 varchar(20),c2 varchar(20),c3 varchar(20));CREATE TABLEtestdb=# testdb=# insert into t_include(id,c1,c2) select x,'c1'||x,'c2'||x from generate_series(1,10000) as x;INSERT 0 10000testdb=# testdb=# create index idx_t_include_id on t_include(id) include (c1);CREATE INDEXtestdb=# testdb=# analyze t_include;ANALYZEtestdb=# explain verbose select id,c1 from t_include; QUERY PLAN ----------------------------------------------------------------------- Seq Scan on public.t_include (cost=0.00..163.00 rows=10000 width=10) Output: id, c1(2 rows)testdb=# testdb=# explain verbose select id,c1 from t_include where id = 1; QUERY PLAN ----------------------------------------------------------------------------------------------- Index Only Scan using idx_t_include_id on public.t_include (cost=0.29..8.30 rows=1 width=10) Output: id, c1 Index Cond: (t_include.id = 1)(3 rows)testdb=#
New Data Type
创建类型complex以及数据表
testdb=# create type complex as (re float, im float);CREATE TYPEtestdb=# create table numbers(x complex);CREATE TABLEtestdb=# insert into numbers values ((0.0, 10.0)), ((1.0, 3.0)), ((1.0, 1.0));INSERT 0 3testdb=# select * from numbers order by x; x -------- (0,10) (1,1) (1,3)(3 rows)
创建比较函数
testdb=# testdb=# create function modulus(a complex) returns float as $$testdb$# select sqrt(a.re*a.re + a.im*a.im);testdb$# $$ immutable language sql;CREATE FUNCTIONtestdb=# testdb=# create function complex_lt(a complex, b complex) returns boolean as $$testdb$# select modulus(a) < modulus(b);testdb$# $$ immutable language sql;CREATE FUNCTIONtestdb=# testdb=# create function complex_le(a complex, b complex) returns boolean as $$testdb$# select modulus(a) <= modulus(b);testdb$# $$ immutable language sql;CREATE FUNCTIONtestdb=# testdb=# create function complex_eq(a complex, b complex) returns boolean as $$testdb$# select modulus(a) = modulus(b);testdb$# $$ immutable language sql;CREATE FUNCTIONtestdb=# testdb=# create function complex_ge(a complex, b complex) returns boolean as $$testdb$# select modulus(a) >= modulus(b);testdb$# $$ immutable language sql;CREATE FUNCTIONtestdb=# testdb=# create function complex_gt(a complex, b complex) returns boolean as $$testdb$# select modulus(a) > modulus(b);testdb$# $$ immutable language sql;CREATE FUNCTION
创建operator
testdb=# create operator <(leftarg=complex, rightarg=complex, procedure=complex_lt);CREATE OPERATORtestdb=# testdb=# create operator <=(leftarg=complex, rightarg=complex, procedure=complex_le);arg=complex, rightarg=complex, procedure=complex_gt);CREATE OPERATORtestdb=# testdb=# create operator =(leftarg=complex, rightarg=complex, procedure=complex_eq);CREATE OPERATORtestdb=# testdb=# create operator >=(leftarg=complex, rightarg=complex, procedure=complex_ge);CREATE OPERATORtestdb=# testdb=# create operator >(leftarg=complex, rightarg=complex, procedure=complex_gt);CREATE OPERATORtestdb=#
现在可以对complex进行比较了:
testdb=# select (1.0,1.0)::complex < (1.0,3.0)::complex; ?column? ---------- t(1 row)
创建比较函数和opc,在创建opc的时候,pg会自动创建同名的opf
testdb=# create function complex_cmp(a complex, b complex) returns integer as $$testdb$# select case when modulus(a) < modulus(b) then -1testdb$# when modulus(a) > modulus(b) then 1 testdb$# else 0testdb$# end;testdb$# $$ language sql;CREATE FUNCTIONtestdb=# create operator class complex_opstestdb-# default for type complextestdb-# using btree astestdb-# operator 1 <,testdb-# operator 2 <=,testdb-# operator 3 =,testdb-# operator 4 >=,testdb-# operator 5 >,testdb-# function 1 complex_cmp(complex,complex);CREATE OPERATOR CLASStestdb=# select * from pg_opfamily where opfname = 'complex_ops'; oid | opfmethod | opfname | opfnamespace | opfowner --------+-----------+-------------+--------------+---------- 106585 | 403 | complex_ops | 2200 | 10(1 row)
现在可以创建数据类型为complex的Btree索引
testdb=# select amp.amprocnum,testdb-# amp.amproc,testdb-# amp.amproclefttype::regtype,testdb-# amp.amprocrighttype::regtypetestdb-# from pg_opfamily opf,testdb-# pg_am am,testdb-# pg_amproc amptestdb-# where opf.opfname = 'complex_ops'testdb-# and opf.opfmethod = am.oidtestdb-# and am.amname = 'btree'testdb-# and amp.amprocfamily = opf.oid; amprocnum | amproc | amproclefttype | amprocrighttype -----------+-------------+----------------+----------------- 1 | complex_cmp | complex | complex(1 row)testdb=# create index idx_numbers_x on numbers(x);CREATE INDEXtestdb=# analyze numbers;ANALYZEtestdb=# explain select * from numbers order by x; QUERY PLAN -------------------------------------------------------------- Sort (cost=1.14..1.15 rows=6 width=37) Sort Key: x -> Seq Scan on numbers (cost=0.00..1.06 rows=6 width=37)(3 rows)testdb=# set enable_seqscan=off;SETtestdb=# explain select * from numbers order by x; QUERY PLAN ------------------------------------------------------------------------------------ Index Only Scan using idx_numbers_x on numbers (cost=0.13..12.22 rows=6 width=37)(1 row)
到此,相信大家对"PostgreSQL中的Btree索引有什么作用"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
索引
数据
作用
也就是
也就是说
内容
函数
层次
类型
结构
节点
学习
支持
查询
实用
巨大
更深
有序
有数
相同
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
江苏大修管理软件开发公司
网络安全刻不容缓 运营商
军事理论网络安全的重要性
中国国家食品安全风险数据库
打造良好的网络安全环境
网络安全国内哪家做的好
苏州皇禄互联网科技有限公司
数据库编程是指什么
艾尔登之环连不上服务器
数据库dmp是什么
丹徒软件开发项目管理
软件开发培训学校村
wincc服务器与客户机
软件开发后形成的无形资产
thrift 数据库
学完数据库可用于什么技术
跳跃数据库
php跨服务器操作图片附件
exl复制显示的数据库
软件开发分工流程图
潜江订制软件开发公司
纵横网络安全大赛规模
网络安全网站分享
连接百度云数据库
him入侵服务器原视频
不同数据库的内存配置
软件开发了怎么推广
上海云网网络技术
php跨服务器操作图片附件
疫情防控爱国卫生运动网络安全