面试官总是再问什么是索引
提到索引总会迅速的想到B+树索引有关的八股文,但却对索引本身没有概念
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。更通俗的说,索引就相当于目录。 为了方便查找书中的内容,通过对内容建立索引形成目录。而数据库索引是一个文件,无论是维护他所产生的时间消耗,还是他本身的空间消耗,都是他为了更高的效率所产生的小代价
MySQL有哪几种索引类型
- b树
- r树(地理空间用)
- hash
- 全文索引(只有MyISAM有)
为什么B+树一枝独秀,为什么不用b树,不用红黑树,不用hash
- 为什么不用红黑树
红黑树必须都存在内存中,而且二叉的话树过深,频繁IO读写
- 为什么不是B,B+比B高度低
B+树的层级更少;B+树查询速度更稳定[都得走到叶子节点],具备排序功能,全节点遍历快
由于只有叶子节点有数据,所以非叶子节点小,所以一次IO读更多节点。
- 为什么不用hash(hash函数加数组加链表)
hash做不到范围查询,B+树可以分批查找,不用都装入内存,B+树得到的结果是有序的。
hash建立索引需要以全部列作为索引,因此很难支持部分索引的查找
聚簇索引与非聚簇索引
- 数据和索引在一起:聚簇
- 数据的主键和索引在一起:非聚簇
我们自己建的索引基本都是非聚簇索引
联合索引的顺序
我们平常排序的时候,最简单的比如说数字
肯定是先排百位数,再排十位数,再排个位数(听起来像个桶排序)
所以当我们使用联合索引的时候(MySQL可以使用多个字段同时建立一个索引,叫做联合索引),在联合索引中,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引。
因此(a,b,c)的索引不但能用于自身,还可以用于(a,b),(a),(a,c)[没错可以用于ac]
当然不能用于(b,a) (b,c)
一般情况下,将查询需求频繁或者字段选择性高的列放在前面。
桥豆麻袋!(a,b,c)的索引为什么可以ac
建立索引
查询ac
SELECT * FROM user_address WHERE province = '广东'
AND district = '南雄市'
结论:abc联合索引,ac中的c不能命中这三个字段的联合索引,a可以命中,所以possible_keys列会显示使用了联合索引
再次基础上理解最左匹配
- mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配
- =和in可以乱序
比如a=3 and b=4 and c>5 and d=6如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
怎么查看MySQL语句有没有用到索引
type 字段比较重要, 它提供了判断查询是否高效的重要依据依据. 通过 type 字段, 我们判断此次查询是 全表扫描 还是 索引扫描 等。如const(主键索引或者唯一二级索引进行等值匹配的情况下),ref(普通的⼆级索引列与常量进⾏等值匹配),index(扫描全表索引的覆盖索引) 。
通常来说, 不同的 type 类型的性能关系如下: ALL < index < range ~ index_merge < ref < eq_ref < const < system
创建索引的方式
- 在执行CREATE TABLE时创建索引
CREATE TABLE user_index2 (
id INT auto_increment PRIMARY KEY,
first_name VARCHAR (16),
last_name VARCHAR (16),
id_card VARCHAR (18),
information text,
KEY name (first_name, last_name),
FULLTEXT KEY (information),
UNIQUE KEY (id_card)
);
- 使用ALTER TABLE命令去增加索引。
ALTER TABLE table_name ADD INDEX index_name (column_list);
ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。
其中table_name是要增加索引的表名,column_list指出对哪些列进行索引,多列时各列之间用逗号分隔。
索引名index_name可自己命名,缺省时,MySQL将根据第一个索引列赋一个名称。另外,ALTER TABLE允许在单个语句中更改多个表,因此可以在同时创建多个索引。
- 使用CREATE INDEX命令创建。
CREATE INDEX index_name ON table_name (column_list);
创建索引的原则
- 表的某个字段值得离散度越高,该字段越适合选作索引的关键字
- 占用存储空间少的字段更适合选作索引的关键字。
- 存储空间固定的字段更适合选作索引的关键字
- Where子句中经常使用的字段应该创建索引
- 更新频繁的字段不适合创建索引
- 有NULL值不当索引
文章末尾请带上以下文字及链接:本文正在参与「掘金小册免费学啦!」活动, 点击查看活动详情