学点关于索引的知识

首先是从面试题切入吧,比较常问但不复杂.(摘抄)

Q:你们每天这么大的数据量,都是保存在关系型数据库中吗?
A:是的,我们线上使用的是MySQL数据库

Q:每天几百万数据,一个月就是几千万了,那你们有没有对于查询做一些优化呢?
A:我们在数据库中创建了一些索引(我现在非常后悔我当时说了这句话)

Q:那你能说说什么是索引吗?
A:(这道题肯定难不住我啊)索引其实是一种数据结构,能够帮助我们快速的检索数据库中的数据

Q:那么索引具体采用的哪种数据结构呢?
A:(这道题我也背过)常见的MySQL主要有两种结构:Hash索引和B+ Tree索引,我们使用的是InnoDB引擎,默认的是B+树

Q:既然你提到InnoDB使用的B+ 树的索引模型,那么你知道为什么采用B+ 树吗?这和Hash索引比较起来有什么优缺点吗?

Q:刚刚我们聊到B+ Tree ,那你知道B+ Tree的叶子节点都可以存哪些东西吗?
A:InnoDB的B+ Tree可能存储的是整行数据,也有可能是主键的值

Q:那这两者有什么区别吗?
A:(当他问我叶子节点的时候,其实我就猜到他可能要问我聚簇索引和非聚簇索引了)在 InnoDB 里,索引B+ Tree的叶子节点存储了整行数据的是主键索引,也被称之为聚簇索引。而索引B+ Tree的叶子节点存储了主键的值的是非主键索引,也被称之为非聚簇索引

Q:那么,聚簇索引和非聚簇索引,在查询数据的时候有区别吗?
A:聚簇索引查询会更快?

Q:为什么呢?
A:因为主键索引树的叶子节点直接就是我们要查询的整行数据了。而非主键索引的叶子节点是主键的值,查到主键的值以后,还需要再通过主键的值再进行一次查询

Q:刚刚你提到主键索引查询只会查一次,而非主键索引需要回表查询多次。(后来我才知道,原来这个过程叫做回表)是所有情况都是这样的吗?非主键索引一定会查询多次吗?
A:(额、这个问题我回答的不好,后来我自己查资料才知道,通过覆盖索引也可以只查询一次)

Q:不知道的话没关系,想问一下,你们在创建索引的时候都会考虑哪些因素呢?
A:我们一般对于查询概率比较高,经常作为where条件的字段设置索引

Q: 那你们有用过联合索引吗?
A:用过呀,我们有对一些表中创建过联合索引

Q:那你们在创建联合索引的时候,需要做联合索引多个字段之间顺序你们是如何选择的呢?
A:我们把识别度最高的字段放到最前面

Q: 那你知道最左前缀匹配吗?
A:(我突然想起来原来面试官是想问这个,怪自己刚刚为什么就没想到这个呢。)哦哦哦。您刚刚问的是这个意思啊,在创建多列索引时,我们根据业务需求,where子句中使用最频繁的一列放在最左边,因为MySQL索引查询会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。所以当我们创建一个联合索引的时候,如(key1,key2,key3),相当于创建了(key1)、(key1,key2)和(key1,key2,key3)三个索引,这就是最左匹配原则

这位兄嘚面试 我觉得比较能体现当时的情景,同时 从面试上也能看出来,面试难度从小到大,从基础开始循环渐进,(我个人只看面试题就能理解个大概了)

一、索引作用

1.提高查询速度
2.确保数据的唯一性
3.加速表与表之间的连接性
4.使用分组和排序检索数据时,减少分组和排序的时间
5.全文检索搜索优化

二、索引结构

1.普通索引: 基本的索引类型,,没有唯一性的限制。
删除索引: DROP INDEX [indexname] ON ‘表’
创建索引: CREATE INDEX [indexname] ON ‘表’(username)

2.唯一索引: 作用是避免表中某列值不重复,与普通索引类似,值可以为空,不同的是,索引列的值必须是唯一,可以有多个

创建索引 CREATE UNIQUE INDEX indexName ON mytable(username(length)) 
修改表结构 ALTER mytable ADD UNIQUE [indexName] ON (username(length)) 
创建表的时候直接指定 CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)))

3.主键索引: 不允许有空值,特殊的唯一索引,在建表的同时创建,(感觉就像是主键)

创建索引 CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID))
当然也可以用 ALTER 命令。
记住:一个表只能有一个主键。

4.组合索引 ::为了形象地对比单列索引和组合索引,为表添加多个字段:

创建索引 CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL, age INT NOT NULL )

为了进一步榨取MySQL的效率,就要考虑建立组合索引。

就是将 name, city, age建到一个索引里:

 ALTER TABLE mytable ADD INDEX username_city_age (username(10),city,age)

建表时,username长度为 16,这里用 10。这是因为一般情况下名字的长度不会超过10,这样会加速索引查询速度,还会减少索引文件的大小,提高INSERT的更新速度。

如果分别在 username,city,age上建立单列索引,让该表有3个单列索引,查询时和上述的组合索引效率也会大不一样,远远低于我们的组合索引。

虽然此时有了三个索引,但MySQL只能用到其中的那个它认为似乎是最有效率的单列索引。
建立这样的组合索引,其实是相当于分别建立了下面三组组合MySQL数据库索引:

username,city,age
username,city
username,age

为什么没有 city,age这样的组合索引呢?

这是因为MySQL组合索引“最左前缀”的结果
比如:这个就会用到:

SELECT * FROM mytable WHREE username="admin"

这个就不会:

SELECT * FROM mytable WHREE age="20"

三、索引底层的一些东西

首先 ,mysql5.5以上默认的存储引擎是innoDb,只显示支持B+树索引,频繁访问的表,innoDb会自适应建立hash索引,这个hash索引是建立在B+树上,方便查询快,用户无法自己指定.

二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。二叉树有如下特性:

1、每个结点都包含一个元素以及n个子树,这里0≤n≤2。
2、左子树和右子树是有顺序的,次序不能任意颠倒。左子树的值要小于父结点,右子树的值要大于父结点。

平衡二叉树是一种特殊的二叉树,所以他也满足前面说到的二叉树的两个特性,同时还有一个特性:

它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

至于B-树和B+树请移步 https://www.cnblogs.com/zhangzhijian/p/11237178.html
(太多了 ,第一次看能看懂80%)

上面这个树的详解 https://blog.csdn.net/kennyrose/article/details/7532032
(这个事避开了详解 ,点中要害,语言简短精炼的那种)

其实研究下来 ,东西没有很复杂 但是量多,比较吃数据结构和空间想象力(我是这么认为,实在不行 拿纸拿笔画一画)
要经常提醒自己回过头看看,很容易忘

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值