类似于字典中查找数据:两种方式,1.通过逐页查找,效率低。2.通过检索目录,直接定位,效率高。
索引就是要查找数据的目录。当对数据建立索引后,oracle会开辟新的存储空间为索引,并且把所有值和rowid存储其中,
当查找的某个信息含有索引时,oracle便改为查找索引,找到其对应的rowid,然后根据rowid检索到对应的信息。
索引说明:
- 索引是建立在表上的可选对象;索引的关键在于通过一组排序后的索引键来取代默认的全表扫描检索方式,从而提高检索效率;
- 索引在逻辑上和物理上都与相关的表和数据无关,当创建或者删除一个索引时,不会影响基本的表;
- 索引一旦建立,在表上进行DML操作时(例如在执行插入、修改或者删除相关操作时),oracle会自动管理索引,索引删除,不会对表产生影响;
- 索引对用户是透明的,无论表上是否有索引,sql语句的用法不变;
- oracle创建主键时会自动在该列上创建索引。
为什么使用索引:
1. 若没有索引,搜索某个记录时(例如查找name='wish')需要搜索所有的记录,因为不能保证只有一个wish,必须全部搜索一遍;
2. 若在name上建立索引,oracle会对全表进行一次搜索,将每条记录的name值哪找升序排列,然后构建索引条目(name和rowid),存储到索引段中,查询name为wish时即可直接查找对应地方;
3. 创建了索引并不一定就会使用,oracle自动统计表的信息后,决定是否使用索引,表中数据很少时使用全表扫描速度已经很快,没有必要使用索引。
创建员工表:
-- Create table
create table EMP
(
empno NUMBER(4) not null,
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2)
);
-- Create/Recreate primary, unique and foreign key constraints
alter table EMP
add constraint PK_EMP primary key (EMPNO);
插入多条数据(建议5w以上):
通过没有建立索引的列进行查询:
通过主键查询:
从上可以很明显的看出,根据主键EMPNO查询时间短的多些。
这是因为:
创建主键的时候自动给主键添加了索引,且该索引为唯一性索引。
即主键一定是唯一性索引。
但是一张表中可以有多个唯一性索引,所以唯一性索引不一定是主键。
1、普通索引
普通索引的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHERE column = )或排序条件(ORDER BY column)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。
2、唯一索引
普通索引允许被索引的数据列包含重复的值。比如说,因为人有可能同名,所以同一个姓名在同一个“员工个人资料”数据表里可能出现两次或更多次。
如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。这么做的好处:一是简化了SQL对这个索引的管理工作,这个索引也因此而变得更有效率;二是SQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,SQL将拒绝插入那条新记录。也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。
索引使用(创建):
创建索引:
CREATE [UNIQUE] | [BITMAP] INDEX index_name --unique表示唯一索引
ON table_name([column1 [ASC|DESC],column2 --bitmap,创建位图索引
[ASC|DESC],…] | [express])
[TABLESPACE tablespace_name]
[PCTFREE n1] --指定索引在数据块中空闲空间
[STORAGE (INITIAL n2)]
[NOLOGGING] --表示创建和重建索引时允许对表做DML操作,默认情况下不应该使用
[NOLINE]
[NOSORT]; --表示创建索引时不进行排序,默认不适用,如果数据已经是按照该索引顺序排列的可以使用
例如,
创建商品表:
-- Create table
create table TB_GOODS
(
goods_id VARCHAR2(64) not null,
goods_name VARCHAR2(256) not null,
goods_price VARCHAR2(64) not null,
status VARCHAR2(1) not null
);
创建索引:
--这里unique可以省略,若省略则索引为非唯一索引
create index UI_tb_goods on tb_goods(goods_name);
--若使用unique则为唯一索引
create unique index un_tb_goods on tb_goods(goods_name);
--括号中添加两列则为组合索引
create unique index un2_tb_goods on tb_goods(goods_name,status);
--括号中添加三列,其顺序没有关系,效果是一样的
create unique index un3_tb_goods on tb_goods(goods_name,goods_price,status);
唯一索引的另一个作用,控制该列不能有相同值!
查询索引:
select * from user_indexes where table_name='表名';
select * from user_ind_columns where index_name='索引名';