数据库索引是什么

今天学习了一些数据库索引的知识简单整理一下,做个记录:

一、什么是索引?

1.一句话总结:索引是用来存储数据表中指定列值的一种数据结构,可以有效提高检索速度。

2.既然索引是一种数据结构,哪些数据结构用于索引:

  1).B-Tree(B-树)--是最常用的用于索引的数据结构

      特性:⑴时间复杂度低, 查找、删除、插入操作都可以在对数时间内完成。

                 ⑵ 在B-Tree中的数据是有序的。

  2).哈希索引--寻找值时哈希表效率极高,对于比较字符串是否相等的查询能够极快的检索出值

      特性:⑴哈系索引是将列的值作为索引的键值(key),和键值相对应实际的值(value)是指向该表中相应行的指针

      缺点:⑵无顺的数据结构,对于对比数据大小时间长短等方面不如B-tree效率高 。

  3).R-Tree

      特性:常用来解决空间问题(比如“查询出所有距离我两公里之内的星巴克”)

  4).位图索引

      特性:这类索引适合放在包含布尔值(true 和 false)的列上。

3.索引的类型

主键索引(PRIMAY KEY)

唯一索引(UNIQUE)

常规索引(INDEX)

全文索引(FULLTEXT)

normal即常规的B-Tree索引,字段值没限制

unique是唯一索引,列中字段值不允许重复

二、索引是如何提高查询性能的?

1、有序性:

     假设我们在表Employee的 Employee_Name这一列上创建一个B-Tree索引。这意味着当我们用SQL(SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’) 查找姓名是‘Jesus’的雇员时,不需要再扫描全表。而是用索引查找去查找名字为‘Jesus’的雇员,因为索引已经按照按字母顺序排序。索引已经排序意味着查询一个名字会快很多,因为名字少字母为‘J’的员工都是排列在一起的。

2、指针:

   索引中除了存储列的值,还存储着一个指向在行数据的索引。也就是说,索引中的Employee_Name这列的某个值(或者节点)可以描述为 (“Jesus”, 0x82829), 0x82829 就是包含 “Jesus”那行数据在硬盘上的地址。如果没有这个引用,你就只能访问到一个单独的值(“Jesus”),而这样没有意义,因为你不能获取这一行记录的employee的其他值-例如地址(address)和年龄(age)。

3、数据库自动识别

   当这个SQL (SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’ )运行时,数据库会检查在查询的列上是否有索引。假设Employee_Name列上确实创建了索引,数据库会接着检查使用这个索引做查询是否合理。(补充但是有些场景下,使用索引比起全表扫描会更加低效)

三、如何创建索引?

1、创建索引

创建标准索引: CREATE  INDEX 索引名 ON 表名 (列名)  TABLESPACE 表空间名; 

创建唯一索引: CREATE unique INDEX 索引名 ON 表名 (列名)  TABLESPACE 表空间名; 

创建组合索引: CREATE INDEX 索引名 ON 表名 (列名1,列名2)  TABLESPACE 表空间名; 

创建反向键索引: CREATE INDEX 索引名 ON 表名 (列名) reverse TABLESPACE 表空间名; 
2、索引使用原则

索引字段建议建立NOT NULL约束 

经常与其他表进行连接的表,在连接字段上应该建立索引; 

经常出现在Where子句中的字段且过滤性很强的,特别是大表的字段,应该建立索引; 

可选择性高的关键字 ,应该建立索引; 

可选择性低的关键字,但数据的值分布差异很大时,选择性数据比较少时仍然可以利用索引提高效率 

复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:

A、正确选择复合索引中的第一个字段,一般是选择性较好的且在where子句中常用的字段上; 

B、复合索引的几个字段经常同时以AND方式出现在Where子句中可以建立复合索引;否则单字段索引; 

C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引; 

D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段; 

E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引; 

频繁DML的表,不要建立太多的索引; 

不要将那些频繁修改的列作为索引列; 

四、索引的缺点以及什么情况下索引会失效?
1、索引会占用空间 - 你的表越大,索引占用的空间越大

2、性能损失(主要值更新操作),当你在表中添加、删除或者更新行数据的时候, 在索引中也会有相同的操作

3、如果条件中有or,即使其中有条件带索引也不会使用(要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引

4、.like查询是以%开头

5、如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

6、如果mysql估计使用全表扫描要比使用索引快,则不使用索引

查看索引的使用情况:

show status like ‘Handler_read%’;
注意:
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数

handler_read_rnd_next:这个值越高,说明查询低效

7、not in ,not exist

8、单独引用复合索引里非第一位置的索引列. 

9、使用Oracle内部函数导致索引失效.对于这样情况应当创建基于函数的索引. 
错误的例子:select * from test where round(id)=10; 
说明,此时id的索引已经不起作用了

正确的例子:首先建立函数索引, 
create index test_id_fbi_idx on test(round(id)); 
然后 select * from test where round(id)=10; 这时函数索引起作用了

10、<> 或者单独的>,<

 

学习文章:

https://www.jianshu.com/p/b72d3ab9e54a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值