赞
踩
索引记录了表中一列或者多列的值与其物理位置之间的对应关系
建立索引的好处是加快对表中记录的查找或者排序
btree
hash
gist
sp-gist
gin
bitmap
原理
bitmap索引是Greenplum的索引接口,类似GIN倒排,只是bitmap的KEY是列的值,VALUE是BIT(每个BIT对应一行),而不是行号list或tree。
应用场景
当某个字段的唯一值个数在100到10万之间(超出这个范围,不建议使用bitmap)时,如果表的记录数特别多,而且变更不频繁(或者是AO表),那么很适合BITMAP索引,bitmap索引可以实现快速的多个或单个VALUE的搜索。因为只需要对行号的BITMAP进行BIT与或运算,得到最终的BITMAP,从最终的BITMAP映射到行进行提取。
bitmap与btree一样,都支持 等于,大于,小于,大于等于,小于等于的查询。
CREATE TABLE contacts( id int primary key, name varchar(40), phone varchar(32)[], address text ); 1、B-tree索引 create index idx_contacts_name on contacts(name); 2、数组索引,GIN索引 create index idx_contacts_phone on contacts using gin(phone); 想要查询号码13422334455是谁的 SELECT * FROM contacts WHERE phone @> array['13422334455'::varchar(32)]; @>是数组的操作符,表示包含,GIN索引能在@>上起作用 注:phone在contacts表中是一个数组类型 3、hash索引的更新不会记录到WAL日志中,所以实际上用得少 4、降序索引 create index idx_contacts_name on contacts(name desc); 5、指定存储参数 create index idx_contacts_name on contacts(name) with(fillfactor=50); 6、指定空值排在前面 create index idx_contacts_name on contacts(name desc nulls first); 7、指定空值排在后面 create index idx_contacts_name on contacts(name DESC NULLS LAST);
在创建索引时,PG会锁表以防止写入,然后对表做全表扫描,完成索引创建操作,此时其他用户可以读取表,但是插入、更新、删除等操作会一直被阻塞,直到索引创建完毕。
若表更新比较 频繁,且表大,这种方式创建索引是不可以接受的。
CREATE TABLE testtab01(id int primary, note text);
插入测试数据
INSERT INTO testtab01 select generate_series(1,5000000),generate_series(1,5000000);
DROP INDEX idx_testtab01_note;
CREATE INDEX CONCURRENTLY idx_testtab01_note on testtab01(note);
开启另一个窗口,其删除操作也不会等待
DELETE FROM testtab01 where id=2;
索引改名
alter index idx_contacts_name rename to idx_contacts_name_new;
索引移动表空间
alter index idx_contacts_name set tablespace tb_test;
设置索引填充因子
alter index idx_contacts_name set (fillfactor = 75);
把索引的填充因子设置为默认值
alter index idx_contacts_name reset (fillfactor);
查看索引信息
\d+ idx_contacts_name
DROP INDEX IF EXISTS idx_contacts_name_old; 若有依赖对象依赖这个索引,则使用CASCADE,表示一并删除这些对象删除掉 CREATE TABLE class( class_no int, class_name varchar(40) ); CREATE UNIQUE INDEX index_unique_class_no ON class(class_no); CREATE TABLE student( student_no int primary key, student_name varchar(40), age int, class_no REFERENCES class(class_no) ); DROP INDEX index_unique_class_no CASCADE;
原子性atomicity
一致性consistency
隔离性isolation
持久性durability
PG与其他数据库最大的区别是,大多数DDL可以包含在一个事务中,而且是可以回滚的。
(1)psql的默认下,每执行一条Sql语句,都会自动提交
关闭
\set AUTOCOMMIT off
\echo :AUTOCOMMIT
(2)显示使用BEGIN:启动一个事务,相当于关闭了自动提交
begin:
insert into testtab01 values(1);
select * from testtab01;
rollback;
大的事务可以分为几个部分,第一个部分成功后,可以建一个保存点,若后面的都失败了,可以回滚到这个保存点
begin;
insert into testtab01 values(1);
savepoint my_savepoint01;
回滚到上一个保存点
rollback to SAVEPOINT my_savepoint01;
READ UNCOMMITTED读未提交
READ COMMITTED读已提交
REPETABLE READ重复读
SERIALIZABLE串行化
并发事务不一致级别
PG默认的隔离级别是读已提交
多台数据库之间的原子性,需要通过两阶段来实现,两阶段提交时实现分布式事务的关键。
set max_prepared_transaction=10; pg_ctl stop -D $PGDATA pg_ctl start -D $PGDATA psql postgres vim postgresql.conf修改max_prepared_transaction=10 create table testtab01(id int primary key); 启动一个事务 begin; insert into testtab01 values(1); 事务第一阶段提交:准备事务提交 osdba_global_trans_0001是全局事务的ID,PG数据库一旦成功执行这条命令,就会把事务持久化 PREPARE TRANSACTION 'osdba_global_trans_0001' 事务第二阶段提交:真正事务提交 COMMIT PREPARED 'osdba_global_trans_0001'
当要查询、插入、更新、删除表中的数据时,首先要获得表上的锁,然后再获得行上的锁
表级锁
行级锁与表级锁冲突
行级锁
PG中,事务自己的锁是从不冲突的,所以一个事务可以持有SHARE锁,再请求一个ROW EXCLUSIVE锁,也不会阻塞自己
显式在表上加锁
LOCK TABLE
由SELECT命令添加
通过查询系统视图pg_locks来查找
psql postgres select pg_backend_pid(); 锁定一张表 begin; lock table testtab01; 查看数据库中锁的情况 select locktype, relation::regclass as rel, virtualxid as vxid, transactionid as xid, virtualtransaction as vsid2, pid, mode, granted from pg_locks where pid = 8127; 想要查看被锁住的进程,只要查看视图pg_locks中granted字段的值为False的进程就就可以了; 行锁 加上行锁,是先在表上加一个表级意向锁,在相应主键上加意向锁; 行锁是会在数据行上加上自己的xid,另一个进程读到这一行时,若发现有行锁,会把行上另一个事务的xid 读取出来,然后再找个xid上加上Share锁,由于之间持有行锁的进程已经在此xid上加了Exclusive的锁, 所以后面要更新这行的进程会被阻塞。 begin; select * from testtab01 where id=1 for update; 判断哪一行被阻塞了? 在sql上加上page和tuple字段,这两个字段组合就是系统字段ctid select locktype, relation::regclass as rel, page||','tuple as ctid virtualxid as vxid, transactionid as xid, virtualtransaction as vsid2, pid, mode, granted from pg_locks where pid = (8416,8112); SELECT * FROM testtab01 WHERE ctid='(0,1)';
virtualxid 与virtualtransaction 关系
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。