数据库(database)是由若干表空间(tablespace)组成。
表空间分为以下:系统表空间、临时表空间、回滚表空间、数据表空间
tablespace是由若干段(segment)组成,segment又由若干区(extent)组成,区又由最小单位(block)组成。表空间、段、区、块。一般建立的表:用几个区组成。
oracle最小扩展单位是区(extent),最小逻辑单位是块(block),默认大小是8kb。
索引的三大特点
1.索引树的高度一般比较低
2.索引由索引列存储的值及rowid组成
3.索引本身是有序的
索引的高度一样,500万条数据5000万条数据,如果根据id去查,产生的io次数是一样的,查询的时间也是一样的。
查询的数据量比较大,不建议走索引,因为根据索引查询,查一条数据要3到4次io,再乘以记录数,还不如走全表扫描
全表扫描是读取一个块、一个块读取的。(所以访问数据量比较大,更不建议走索引)。
为什么大表拆小表查询快?
表存储的最小单位是block,读取的时候是一个一个block读取,小表io读减少。
什么是逻辑读?
就是一个block一个block的读
索引列为空对走索引有影响解决办法:
1.告诉数据库该列不为空
2.建立该字段的时候,告诉数据库该字段不为空
3.如果是主键则不会产生该问题
索引扫描类型?
index full scan (min/max),一次读取一个块,可以保证有序(max min 显然是有序,union )
index range scan
index fast full scan (sum/avg/count),一次读取所有的块,不保证有序(count sum不需要保证有序,union all)
select min(id),max(id) from t的写法能用到索引吗?
分成两条语句读select maxValue,minValue from(select max(id) as maxValue from t) a,(select min (id) as minValue from t)b
消除table access by index rowid
select * from t where t=1 (需要回表读)
select id from t where t=1 (消除了回表读的操作)
如果业务需要,可以建立组合索引进行优化,比如:select id,name from t,把id,name建立成组合索引。
联合索引的建立势必会让block变多,组合索引的列不宜超过3个
set autotrace on 跟踪查询计划
聚合因子:
10条数据放在一个block,聚合因子比较低
10条数据放在10个block,聚合因子比较高
create table 是不走缓存,所以比insert into 快很多
排序主要是消耗在cpu上,如果pga无法容纳排序的数据,将在磁盘上排序,性能消耗更大。
使用索引可以消除排序,但是查出大量的数据的时候,走索引是通过回表读所以产生的io的消耗更大。产生的逻辑读会比没建立索引大很多。如果可以消除回表都消耗更小。
distinct 采用的是HASHUNIQUE的算法,distinct也会产生排序
组合索引建立的规则:
1.(col1,col2) 查询时select * from t where col=xx and col2=xx,无论col1和col2在前后,其实都是一样的效果。
2.(co1,col2) 查询时select * from t where col=xx and col2>xx ,这种情况col1在前效率更高
联合索引的前一列不需要建立索引
alter index 索引名 monitoring usage;
通过观察v$object_usage 进行跟踪
select * from v$object_usage;
避免列运算让索引失效,如果真的有需要,可以考虑建立函数索引
位图索引和b树索引最大的区别。
叶子节点保存的是 每一条记录的状态,标记为0或者1 比如5条记录,前面两条是男:男 11000
位图索引的记录格式是:
键值
开始rowid:
结束rowid
对应数值。
采用位图索引,一个键指向多行,可能数以百计甚至更多。如果更新一个位图索引键,那么这个键指向的数百条记录会与你实际更新的那一行一同被有效地锁定。
所以,如果有人插入一条新记录(PROCESSED_FLAG列值为N),就会锁定位图索引中的N键,而这会有效地同时锁定另外数百条PROCESSED_FLAG列值为N的记录(以下记作N记录).