面试-MySQL
面试-MySQL
索引是什么
问:索引是什么
答:索引(index)是帮助数据库高效获取数据的数据结构。MySQL数据库默认采用的是B+Tree的数据结构。其所有的数据都存储在叶子节点,非叶子节点仅用于索引数据。叶子节点形成了一个双向链表,便于数据的排序及区间范围查询。
-- 创建索引语句
CREATE INDEX 索引名 ON 表名(列名1, 列名2...);
-- 创建表的时候加索引
CREATE TABLE 表名 (
列名1 数据类型,
列名2 数据类型,
列名3 数据类型,
-- 唯一索引
UNIQUE KEY 索引名 (列名2),
-- 普通索引(KEY和INDEX 等价,KEY更简洁)
KEY 索引名 (列名2)
);
InnoDB索引与MYISAM索引实现的区别
问:InnoDB索引与MYISAM索引实现的区别
答:InnoDB是聚簇索引(数据即索引),MyISAM 是非聚簇索引(索引与数据分离)。两者底层都用B+Tree。如果是主键查询则InnoDB只需一次B+Tree查找然后直接取数据,而MYISAM的索引与数据是不同的文件会先在索引文件中查其在数据文件中的位置然后再从数据文件中取出数据。
聚簇索引与非聚簇索引
问:聚簇索引与非聚簇索引
答:聚簇索引:数据与索引放到一块,B+Tree树的叶子节点保存了整行数据。
非聚簇索引(二级索引):数据与索引分开,B+Tree的叶子节点保存对应的主键,要想获取数据需要先走非聚簇索引获取对应主键,再根据主键走聚簇索引获取整行数据即回表操作。
覆盖索引与非覆盖索引
问:覆盖索引与非覆盖索引
答:覆盖索引:指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到。比如只给name字段和age字段增加了索引,返回的列只有name或者只有age或者既有name也有age就是覆盖索引。如果返回的列有address等其它字段就是非覆盖索引则查询数据时需要多一步回表查询。
MySQL超大分页怎么处理
问:MySQL超大分页怎么处理
答:在数据量比较大时,limit分页查询,需要对数据进行排序,效率低。解决方案:覆盖索引 + 子查询
-- 原SQL
select * from tb_sku limit 9000000, 10
-- 优化后
select
a.*
from
tb_sku as a,
inner join
(select id from tb_sku order by id limit 9000000, 10) as b
on a.id = b.id
MySQL为什么使用B+Tree作为索引结构
问:MySQL为什么使用B+Tree作为索引结构
答:B树是一种多路平衡树,用其存储大量数据,整个树的高度相比二叉树来说会矮很多。树的高度决定磁盘IO的次数,树越矮,次数越少就越快。
相比较与B树,B+Tree所有的数据都存储在叶子节点并且使用双向链表的方式进行关联,非叶子节点只存储索引。B+Tree非叶子节点不存储数据,所以每一层能够存储的索引数量会增加,意味着B+树在层高相同的情况下存储的数据量要比B树要多,使得磁盘IO次数更少。
在MySQL里面,范围查询是一个比较常用的操作,而B+Tree的所有存储在叶子节点的数据使用了双向链表来关联,所以在查询的时候只需查两个节点进行遍历就行,而B树需要获取所有节点,所以B+Tree在范围查询上效率更高。
因为B+Tree叶子节点存储所有数据,所以B+Tree的全局扫描能力更强一些,因为它只需要扫描叶子节点。但是B树需要遍历整个树。
为什么建议使用自增长主键作为索引
问:为什么建议使用自增长主键作为索引
答:自增主键能够维持底层数据顺序写入,顺序写入比随机写入快很多
读取可以由B+Tree树的二分查找定位
支持范围查找,范围数据自带顺序
索引失效场景
问:索引失效场景
答:使用函数或者计算导致索引失效
like以%开头导致索引失效
不等于导致索引失效
类型转换导致索引失效
-- 使用函数导致索引失效
select * from emp where left(name, 3) = 'abc'
-- like以%开头导致索引失效
select * from emp where name like '%ab%'
-- 不等于导致索引失效
select * from emp where name <> 'abc'
like以%开头会导致索引一定失效吗?
问:like以%开头会导致索引一定失效吗?
-- 非覆盖索引会失效
select * from user where name like '%三'
-- 覆盖索引不会失效
select name from user where name like '%三'
count(*)和count(列名)有什么区别
问:count(*)和count(列名)有什么区别
答:count(*)会统计值为null的行
count(列名)不会统计值为null的行
日常工作中怎么优化SQL
问:日常工作中怎么优化SQL
答:加索引
减少返回的数据列
避免走全表扫描、避免子查询
分库分表
如何定位慢查询
问:如何定位慢查询
答:使用外部工具监控接口,查看接口调用时间。也可以使用MySQL自带的慢日志查询,其能记录所有执行时间超过指定参数的所有SQL语句日志,MySQL默认不开启慢查询日志,需要自己配置开启。
SQL语句执行很慢,如何分析
问:SQL语句执行很慢,如何分析
答:在select语句之前加上关键字explain可以查看SQL语句的执行计划,可以看这条SQL有没有走索引、是否存在全盘扫描等等
事务的四大特性
问:事务的四大特性
答:事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
原子性:事务是不可分割的最小操作单位,要么全部成功,要么全部失败
一致性:事务完成时,必须使所有的数据都保持一致状态
隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响下的独立环境下运行
持久性:事务一旦提交或回滚,它对数据库中的数据改变就是永久的
并发事务带来的问题
问:并发事务带来的问题
答:脏读:一个事务读取到另外一个事务还没有提交的数据
不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同
幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据行时又发现这行数据已经存在
MySQL默认隔离级别
问:MySQL默认隔离级别
答:隔离级别:读未提交(什么都不能解决)、读已提交(能解决脏读)、可重复读(MySQL默认,能解决脏读、不可重复读)、串行化(能解决脏读、不可重复读、幻读)。
MySQL主从同步原理
问:MySQL主从同步原理
答:MySQL主从复制的核心就是二进制日志BinLog文件,主库在事务提交时,会把数据变更记录在二进制日志文件binlog中,从库读取主库的binlog文件,写入到从库的中继日志Relay Log文件中,从库重做中继日志中的事件,将改变反映它自己的数据。
数据库连接池有什么用
问:数据库连接池有什么用
答:首先,数据库连接池是一种池化技术,池化技术的核心思想是实现资源的复用,避免资源重复创建销毁的开销。而在数据库的应用场景里面,应用程序每次向数据库发起CRUD操作的时候,都需要创建连接。在数据库访问量较大的情况下,频繁的创建连接会带来较大的性能开销。而连接池的核心思想,就是应用程序在启动的时候提前初始化一部分连接保存到连接池里面,当应用需要使用连接的时候,直接从连接池获取一个已经建立好的链接。避免了每次连接的建立和释放带来的开销。
数据库连接池有哪些关键参数
问:数据库连接池有哪些关键参数
答:初始化连接数、最大连接数、最大空闲连接数、最小空闲连接、最大等待时间、无效连接清除
