MYSQL——MYSQL中的索引问题总结

1、什么是索引?索引加越多越好吗?

索引就类似于图书的目录,可以加快你找到某一个文章的速度。所以所MYSQL中的索引可以大大提高查询速度。

要注意的是,索引并不是越多越好。
(1)索引也是表的组成部分,建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件。
(2)对于一个经常需要更新和插入的表格,就没有必要为一个很少使用的where字句单独建立索引了。
(3)对于比较小的表,排序的开销不会很大,也没有必要建立索引。

所以我们一般是为一些经常进行较大量查询的表的字段建立索引,并且需要合理建立索引,而不是越多越好,应该达到一个合理平衡。

2、有哪些索引类型?

索引类型有:normal,unique,full text。

(1)NORMAL(普通索引)

普通索引。比较常见。

(2)UNIQUE(唯一索引)

唯一索引,不允许有重复,允许null。如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique。

(3)FULL TEXT(全文索引)

全文索引。仅可用于MyISAM和InnoDB引擎。FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。
它的出现是为了解决WHERE name LIKE “%word%"这类针对文本的模糊查询效率较低的问题。

(4)主键索引

就是根据主键建立索引,不允许重复,不允许null

(5)组合索引

用两个或者多个列组合构建的索引,这多个列中的值不允许有null。

3、有哪些索引方法?

索引方法有hash、b-tree、r-tree。

(1)HASH

由于哈希的唯一以及类似于键值对的形式,所以很适合做索引,一次到位,不需要像树那样逐层遍历,所以查询效率更高。

但是,这种高效是有条件的,即只在“=”和“in”条件下高效,对于范围查询、排序及组合索引仍然效率不高。

InnoDB引擎有一个特殊功能叫“自适应哈希索引”。当InnoDB发现某些索引值被使用的非常频繁是,会在内存中基于B-Tree索引之上再建一个哈希索引,这样可以让B-Tree索引具有哈希索引的优点。这是一个完全自动的、内部的行为,用户无法控制或配置(如果有必要,可以关闭该功能)。

(2)B-TREE

使用最多。BTREE索引就是一种将索引值按一定的算法,存入一个树形的数据结构中,每次查询都是从树的入口root开始,依次遍历node,获取leaf。这是MySQL里默认和最常用的索引类型。

(3)R-TREE

RTREE在MySQL很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。

相对于BTREE,RTREE的优势在于范围查找。

4、为什么使用索引?

首先,索引是一个排序的列表。
在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址,在数据十分庞大的时候,索引可以大大加快查询的速度,这是因为使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据。

索引(1)可以快速检索,(2)减少I/O次数,加快检索速度;(3)根据索引分组和排序,可以加快分组和排序;

5、创建、使用索引时要注意什么?

(1)首先我们在创建索引时
第一是可以考虑使用覆盖索引,可以减少回表的次数。mysql5.6版本的新特性:先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,进一步减少回表次数。最后再用 WHERE 子句中的其他条件去过滤这些数据行。这个是可以在explain执行计划里面extra字段里面显示using index condition是可以看出来的。
我们可以将最左原则和覆盖索引配合,减少对索引的维护。

第二点是对于写多读少的服务,如果说对于唯一性的要求不高或者通过业务代码可以保证唯一性的时候可以考虑使用普通索引。因为普通索引是会用到change buffer的,它可以把一些写操作缓存下来,读的时候进行merge操作。这样可以提高写入的速度,以及内存的命中率。

第三点是,因为建立索引的时候要对表加锁,因此注意在业务空闲的时候进行。

(2)另外,如果使用过程中发现索引走不上,我们应该怎么排查?
第一,可能是我们自身的SQL有问题。比如说(1)是不是对索引字段使用了!=、or、或者函数操作;(2)组合索引中,是不是符合最左前缀原则;(3)like的模糊查询,使用%开头,不会使用索引;(4)是不是连接查询的时候,两个表的编码方式不同,或者进一步来说两个表的字段类型是不是不一样?

第二可以考虑索引统计信息是不是有问题?我们可以使用analyze table重新统计索引信息。

6、谈谈什么是最左匹配?对组合索引的理解?

对于组合索引来说,列的顺序很重要,MySQL仅能对索引最左边的列进行有效的查找。一般遵循最左匹配原则。

例如:
假设存在组合索引(c1,c2),查询语句
select * from t1 where c1=1 and c2=2
能够使用该索引。查询语句
select * from t1 where c1=1
也能够使用该索引。但是,查询语句
select * from t1 where c2=2
不能够使用该索引,因为没有组合索引的引导列,即,要想使用c2列进行查找,必需出现c1等于某值。

建立联合索引时,从左到右依次判断,如果左边列相同,则根据第二列的大小排列,多列以此类推。

7、索引的底层结构?B+树的特点?为什么B+树更适合做索引?

我们先要了解一下树结构:数据结构——树(各种树)

首先我们知道B树适用于文件系统,因为减少数据加载到内存中的数据量,每次只需要加载一个节点的数据就可以。
而数据库的SELECT查询操作,更多的时候需要查询多条数据且需要做排序。如果使用B树的话,获取到所有的数据就需要做中序遍历,而B+树的所有数据都在叶子节点上,叶子节点又是链表结构,只需要找到首尾,就可以查询到所需的数据。

8、有没有遇到过慢查询?如何优化?

在项目中遇到过,查询慢,作业现场一些功能卡顿时间较长的现象。

(1)怎样会导致慢查询?

(1)不加索引。
建表不加索引,或者加了索引也没用上,或者使用方式不对(比如说组合索引不是使用的索引中的最左列字段)。

(2)select*
select * where xxx=xxx 不管是啥,所有字段都查出来。

(3)select xxx limit 100000
符合条件的数据量有多少,全部拿出来。

(4)join各种表
join各种表,连接一万遍。

(2)怎样优化慢查询?

首先我们可以使用explain查看MYSQL的执行计划。
详细链接:explain执行计划结果分析

具体的优化方法有:

索引:
(1)合理使用覆盖索引;
(2)索引中的字段数建议不超过5个。
SQL:
(1)避免使用select*
(2)避免对索引字段使用函数或者运算
(3)避免使用in、or、join等
建表:
(1)每一列都是not null,若允许null值,mysql会维护一个null值列表,存储上、查询上都增加了成本。
(2)能用固定长度数据类型解决的,不用变长类型。

(3)有没有遇到过索引建的不好,导致索引走的很差的情况?

遇到这种情况的话,
首先我们可以考虑使用force index,强制走索引,但是这个不太好,可以作为业务的应急预案。可能换了数据库就不支持了,还需要我们做一个代码的重新发布。(force index用例参考:MySQL FORCE INDEX 强制索引使用

第二个呢,就是我们可以考虑用覆盖索引加最左原则,考虑是不是把选错的索引删掉,也是比较常用的一个优化方案。

9、介绍一下MYSQL中的锁?

MYSQL——MYSQL中的锁

10、MYSQL中的主从是怎样同步的?

11、MYSQL中的主从同步延迟问题?

12、MySQL中varchar与char的区别以及char(10)中的10代表的涵义?

从表面来看char是定长,varchar是变长。
也就是说当将两者的长度都定为10,然后向其中存入一个字符串“good”,显然字符串“good”的长度不到10,当定义类型为char类型时,存入的长度依旧是10,由字符串“good”和后面的6个空格组成。当我们定义为varchar类型时,长度就变为了4,“good”字符串原有的长度。

char是以空间换取时间效率,而varchar是以空间效率为首位的。

在获取数据时,char类型的数据需要使用trim()方法,去掉字符串后面多余的空格。但varchar不需要。

以上理解是比较狭隘的。待后续成长后补充修改。。。

13、MYSQL中的事务隔离级别以及区别?

MYSQL默认的事务隔离级别:Repeatable Read。

具体见以下链接:MySql数据库的事务、ACID以及事务隔离机制

14、MYSQL中的MVCC?

MVCC是一种多版本并发控制机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值