1. 什么是索引?
索引是一种数据结构,可以帮助我们快速进行数据的查找;2. 索引是个什么样的数据结构呢?
索引的数据结构和具体的存储引擎的实现有关,在mysql中常用索引有hash索引和B+树索引,innoDB中默认使用B+树索引;
3. Hash索引和B+树所有有什么区别或者说优劣呢?
两者的原理:
hash索引:底层是hash表,通过调用hash函数获得响应的键值,之后通过这个键值回表查询获得实际的数据;
hash索引的优势在于等值查询的速度,无法进行范围查(因为hash索引顺序与原顺序不一致).无法使用
索引排序,不支持模糊查询,无法避免回表数据查询,并且等值查询的效率并不稳定,有可能效率很差;
B+树索引:底层是多路平衡查找树,每次查询都从根节点出发,查找到叶子节点可以获得所查键值,
然后根据查询判断是否需要回表查询数据.B树因为数据结构优势天然支持范围查询,
B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低.
B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询
所以大多数情况下,B+树索引相对更好.
4. 上面提到了B+树在满足聚簇索引和覆盖索引的时候不需要回表查询数据,什么是聚簇索引?
B树索引中,叶子节点可能存储了当前的key值,也可能存储了当前的key值以及整行的数据,
这就是聚簇索引和非聚簇索引;在InnoDB中,只有主键的叫聚簇索引,如果没有住进,则挑选
一个唯一键建立聚簇索引,如果唯一键也没有,则隐式生成一个键建立聚簇索引.
当查询使用聚簇索引时,在对应的叶子节点,可以获取到整行数据,因此不用再次进行回表查询.
5. 非聚簇索引一定会回表查询吗?
不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询.
举个简单的例子,假设我们在员工表的年龄上建立了索引,那么当进行select age from employee where age < 20的查询时,
在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询.
6. 在建立索引的时候,都有哪些需要考虑的因素呢?
1.字段使用频率;2.如果是联合索引,需要按照索引时的字段顺序使用,否则无法命中索引;3.过多的索引反而会影响数据库的查询效率
7. 联合索引是什么?为什么需要注意联合索引中的顺序?
mysql可以使用多个字段同时建立一个索引,叫做联合索引,同时联合索引在建立时要留意将高频的字段索引放在前面
8. 创建的索引有没有被使用到?或者说怎么才可以知道这条语句运行很慢的原因?
explain命令查看sql语句的执行计划;
9. 那么在哪些情况下会发生针对该列创建了索引但是在查询的时候并没有使用呢?
1.使用!=查询;
2.列参与了数学运算或者函数;
3.查询字符时like的条件里面出现通配符%;
4.mysql分析全表扫描回避使用索引块的时候;
5.使用联合索引时,前面一个条件为范围查询,后面的基石符合最左前缀原则也不能用索引了
10. 什么是事务?
一系列满足ACID特性的操作.这些操作,要么全成功、要么全失败;
11.ACID是什么?可以详细说一下吗?
A:Atomicity原子性,不可分割
C:Consistency 一致性,
I:Isolation 隔离性;
D:Durability 持久性;
12.同时有多个事务在进行会怎么样呢?
多事务会产生问题:脏读,幻读,不可重复读;
13. 怎么解决这些问题呢?MySQL的事务隔离级别了解吗?
Mysql有四种事务隔离级别:未提交读;已提交读;可重复读(mysql默认);可串行化;
14. Innodb使用的是哪种隔离级别呢?
InnoDB默认使用的是可重复读隔离级别.
15.对MySQL的锁了解吗?
mysql从类别上分:有共享锁和排他锁
共享锁用在DQL查询上,也叫读锁,当读取数据时,对数据加上共享锁,共享锁可以同时加多个查询用户;
排他锁用在DML增删改上,也叫写锁,数据写入时,数据加锁,只有当前用户持有,其他执行相同DML操作的用户无法访问,被互斥
锁从粒度区分:行,页,表等几个等级的锁;
16.为什么要尽量设定一个主键?主键使用自增ID还是UUID?
主键可以保证整张表的唯一性,主键也可以快速定位行数据;
推荐自增ID,因为在默认的InnoDB中,主键索引是作为聚簇索引存在的.自增索引可以保证数据的顺序.
17.字段为什么要求定义为not null?
null值会占用更多的空间维护,所以如果可以的话定义一张表的时候尽量减少允许非空列的存在;
18.如果要存储用户的密码散列,应该使用什么字段进行存储?
固定长度的字符应该使用char,这样可以节省空间并且提高效率;
19. MySQL支持哪些存储引擎?
其实mysql支持很多种存储引擎,InnoDB,MyISAM等等
但是选择InnoDB引擎相对合适,也是mysql默认的存储引擎;
InnoDB支持事务,锁的粒度是行级锁,支持MVCC,支持外键,不支持全文索引相对性能优秀;
20.MySQL中的varchar和char有什么区别?
char是定长的字符串,空间占用是固定的而var是变长字符串,存储时如果没有指定长度会默认采用最大长度存储,
从检索效率上讲char的效率也更高;
21.varchar(10)和int(10)代表什么含义?
varchar仅代表申请的长度空间,也就是最大存储数据的长度.
22.超大分页怎么处理?
select * from table where id in (select id from table where age > 20 limit 1000000,10).
这样虽然也load了一百万的数据,但是由于索引覆盖,要查询的所有字段都在索引中,所以速度会很快
解决超大分页,其实主要是靠缓存,可预测性的提前查到内容,缓存至redis等k-V数据库中,直接返回即可.
在阿里巴巴《Java开发手册》中,对超大分页的解决办法是类似于上面提到的第一种
23.对慢查询都怎么优化过?
sql优化:
尽量使用索引查询,少用!=或者in这样的操作符会导致全表扫描;
表数据尽量不要使用null;
尽量少用字符串的模糊通配符%查询;
尽量指定查询的结果字段,而不是用*;
分批处理大批量的数据查询;
条件语句exists效率更高;
select into少用;
另外如果表中数据量过大,可以考虑横向分表或者纵向分表;
24.三个范式
第一范式: 每个列都不可以再拆分.
第二范式: 每一行的数据只能与其中一列相关,即一行数据只做一件事。只要数据列中出现数据重复,就要把表拆分开来
第三范式: 非主键列只依赖于主键,不依赖于其他非主键.数据不能存在传递关系,即没个属性都跟主键有直接关系而不是间接关系