mysql索引
1什么是索引?
索引说白了就是一种数据结构,可以协助快速查询数据,以及更新数据库表中的数据,更通俗的来说索引其实就是目录,通过对数据建立索引形成目录,便于去查询数据,而mysql索引的实现通常是B树和B+树
2索引有哪些优缺点?
索引的优点
可以大大加快数据的检索速度 ,这也是创建索引的最主要的原因。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
索引的缺点
时间方面 :创建索引和维护索引要耗费时间 ,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
空间方面:索引需要占物理空间。
3 索引的使用场景
索引通常可以建立在where,order by语句之后,通过建立索引,避免全表扫描,可以大大的提高查询性能,
同时如果要查询的字段都建立过索引,那么引擎会直接在索引表中查询而不会访问原始数据(否则只要有一个字段没有建立索引就会做全表扫描),这叫索引覆盖。因此我们需要尽可能的在select后只写必要的查询字段,以增加索引覆盖的几率
4 索引有哪几种类型
主键索引 : 数据列不允许重复,不允许为NULL,一个表只能有一个主键 。
唯一索引 : 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引 。
可以通过 ALTER TABLE table_name ADD UNIQUE (column); 创建唯一索引
可以通过 ALTER TABLE table_name ADD UNIQUE (column1,column2);创建唯一组合索引
普通索引 : 基本的索引类型,没有唯一性的限制,允许为NULL值 。
可以通过ALTER TABLE table_name ADD INDEX index_name (column);创建普通索引
可以通过ALTER TABLE table_name ADD INDEX index_name(column1,column2, column3);创建组合索引
全文索引 : 是目前搜索引擎使用的一种关键技术。
可以通过ALTER TABLE table_name ADD FULLTEXT (column);创建全文索引
5 创建索引的原则
索引虽好,但也不是无限制的使用,最好符合一下几个原则
1) 最左前缀匹配原则 ,组合索引非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,
如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
2)较频繁作为查询条件的字段才去创建索引
3)更新频繁字段不适合创建索引
4)区分度不高的字段不适合做索引列 (如性别,男女未知,最多也就三种,区分度实在太低) --当然也不一定,对于一些任务表 我们是可以对任务状态建立索引,以此来检索需要处理的任务状态;
5)尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
6)定义有外键的数据列一定要建立索引 。
7)对于那些查询中很少涉及的列,重复值比较多的列不要建立索引 。
8)对于定义为text、image和bit的数据类型的列不要建立索引。
6 百万级别或以上的数据如何删除并重建
- 所以我们想要删除百万数据的时候可以先删除索引
- 然后删除其中无用数据
- 删除完成后重新创建索引
7 什么是最左前缀原则?
1最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,
比如a = 1 and b = 2 and c > 3 and d = 4
如果建立(a,b,c,d)顺序的索引,d是用不到索引的,
如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整
2 =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
8 B树和B+树的区别
1 对于B+树来说 它的数据是存放在主键索引的叶子节点上的,而对于B树来说,它是将键和值即存放在叶子节点也存放在内部节点
2 B+树的叶子节点之间相互连接,而B树叶子节点之间相互独立
9 使用B+树的好处(为啥使用B+树不使用B树)
很明显 B+树他的特点是数据只存在在主键索引的叶子节点的,而非叶子节点存放的是索引,这也就意味着在相同数据量的情况下,B+树的非叶子节点可以存放更多的索引,树的层级更少,io次数也就更少
同时mysql-innodb存储引擎下它的叶子节点之间用双向指针进行连接(传统的B+树是单向指针)这也就意味着它可以快速的进行范围查找,也就是B+树只需要使用O(logN)时间找到最小的一个节点,然后通过链进行O(N)的顺序遍历即可。
而B树则需要对树的每一层进行遍历,这会需要更多的内存置换次数,因此也就需要花费更多的时间
10 Hash索引和B+树所有有什么区别或者说优劣呢?
首先要知道Hash索引和B+树索引的底层实现原理:
hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据。
B+树底层实现是多路平衡查找树。
对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。
那么可以看出他们有以下的不同:
hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询。 因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询。
而B+树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围。
hash索引不支持使用索引进行排序,原理同上。
hash索引不支持模糊查询以及多列索引的最左前缀匹配 。原理也是因为hash函数的不可预测。AAAA和AAAAB的索引没有相关性。
hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询。
hash索引虽然在等值查询上较快,但是不稳定。性能不可预测,当某个键值存
在大量重复的时候,发生hash碰撞,此时效率可能极差。而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低。
因此,在大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度。而不需要使用hash索引。
11 什么是聚簇索引?何时使用聚簇索引与非聚簇索引
聚簇索引:说白了也就是数据和索引在一块,找到索引也就找到了数据
非聚簇索引:即数据和索引分开存储 ,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因
澄清一个概念:innodb中,在聚簇索引之上创建的索引称之为辅助索引,
辅助索引访问数据总是需要二次查找,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引,辅助索引叶子节点存储的不再是行的物理位置,而是主键值
何时使用聚簇索引与非聚簇索引
12 非聚簇索引一定会回表查询吗?
不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。
举个简单的例子,假设我们在员工表的年龄上建立了索引,那么当进行select age from employee where age < 20的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询。
13 联合索引是什么?为什么需要注意联合索引中的顺序?
MySQL可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,
如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引。
具体原因为:
MySQL使用索引时需要索引有序 ,假设现在建立了"name,age,school"的联合索引,
那么索引的排序为: 先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序 。
当进行查询时,此时索引仅仅按照name严格有序,因此必须首先使用name字段进行等值查询,之后对于匹配到的列而言,其按照age字段严格有序,此时可以使用age字段用做索引查找,以此类推。因此在建立联合索引的时候应该注意索引列的顺序,
一般情况下,将查询需求频繁或者字段选择性高的列放在前面。
此外可以根据特例的查询或者表结构进行单独的调整