一. 索引相关
1: 为什么使用B+树而不是B树或哈希?
B+树:非叶子节点只存key不存data,树高更低;叶子节点双向链表连接,范围查询效率高
B树:每个节点都存data,树高更高;范围查询需要中序遍历
哈希:等值查询快,但不支持范围查询和排序
2: 什么情况下索引会失效?
违反最左匹配原则
在索引列上使用函数或计算
使用 !=、<>、NOT IN
类型转换(如字符串转数字)
LIKE 以通配符开头
3: 如何优化慢查询?
使用 EXPLAIN 分析执行计划
为WHERE、JOIN、ORDER BY字段加索引
避免 SELECT *,使用覆盖索引
优化SQL语句,避免嵌套查询调整数据库参数(缓冲池大小等)
4: 回表查询和覆盖索引是什么?
回表查询:通过非聚簇索引找到主键,再通过主键查找数据行
覆盖索引:索引包含所有查询字段,无需回表
5: 索引的分类?
从物理存储角度上分为聚集(聚簇)索引和非聚集(非聚簇)索引
聚集索引指的是数据和索引存储在同一个文件中
非聚集索引指的是数据和索引存储在不同的文件中
从逻辑角度上分为普通、唯一、主键和联合索引,它们都可以用来提高查询效率,区别点在于
唯一索引可以限制某列数据不出现重复,主键索引能够限制字段唯一、非空
联合索引指的是对多个字段建立一个索引,一般是当经常使用某几个字段查询时才会使用,它比对这几个列单独建立索引效率要高
6.创建索引的原则
1. 主键字段会自动创建主键索引
2. 经常作为查询条件在where和order by语句中出现的列需要建立索引
3. 查询中与其他表关联的字段,外键关系建议建立索引
4. 经常使用多个条件查询时建议使用组合索引代替多个单列索引
5. 用于聚合函数的列可以建立索引
6. 数据量小的表不建议添加索引
7. 不要在区分度低的字段建立索引,比如性别字段
8. 数据变化比较大的表不建议创建索引
二. 性能优化
1: 如何设计数据库分库分表?
-
垂直分库:按业务模块拆分
-
水平分表:按数据范围或哈希分表
-
分片键选择:业务常用查询字段
-
全局ID生成:雪花算法、Redis自增、数据库序列
2: 主从复制原理和延迟问题?
原理:主库binlog → 从库IO线程 → relay log → SQL线程重放
延迟原因:网络、从库性能、大事务、单线程复制
解决方案:并行复制、半同步复制、增加从库、业务读写分离
3、谈谈你对sql的优化的经验
1、表设计方面
1.1 单表数据量大可以考虑分库分表
分库需要借助中间件,比如说mycat 分表的话,比如说可以分成热点数据表和历史数据
1.2 可以添加冗余字段以避免表关联查询
1.3 建表时选择合适的数据类型和长度
2、索引方面
2.1 开启慢查询日志定位执行时间比较长的SQL
2.2 需要创建索引的尽量创建索引,有索引的可以使用explain判断是否走索引
3、SQL语句方面
尽量不使用select *
in 后面不要出现太多的值
避免子查询
4、选择合适的引擎
Innodb MyIsam
三.事务
1、事务的四大特性
事务是有一组操作,要不全部成功要不全部失败,事务的四大特性指的是原子性、一致性、隔离性、持久性
原子性:事务是最小的执行单位,不允许分割,同一个事务中的所有命令要么全部执行,要么全部不执行
一致性:事务执行前后,数据的状态要保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的
隔离性:并发访问数据库时,一个事务不被其他事务所干扰,各并发事务是独立执行的
持久性:一个事务一旦提交,对数据库的改变应该是永久的,即使系统发生故障也不能丢失
2、并发事务(多个事务同事执行)带来的问题
并发事务下,可能会产生如下的问题:
脏读:一个事务读取到了另外一个事务没有提交的数据
不可重复读:一个事务读取到了另外一个事务修改的数据
幻读(虚读):一个事务读取到了另外一个事务新增的数据
3、事务隔离级别
事务隔离级别是用来解决并发事务问题的方案,不同的隔离级别可以解决的事务问题不一样
读未提交: 允许读取尚未提交的数据,可能会导致脏读、幻读或不可重复读
读已提交: 允许读取并发事务已提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
可重复读: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
可串行化: 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,该级别可以防止脏读、不可重复读以及幻读。
上面的这些事务隔离级别效率依次降低,安全性依次升高,如果不单独设置,MySQL默认的隔离级别是可重复读
原理:我知道是MVCC(多版本并发控制),有日志文件和3个隐藏的列处理的
4. MVCC多版本并发控制原理?
-
每行数据有隐藏的创建版本号和删除版本号
-
事务通过版本号快照读取数据
-
READ VIEW决定事务能看到哪些版本
-
通过UNDO LOG实现版本链
5: 乐观锁和悲观锁的区别?
-
悲观锁:假设会冲突,先加锁再操作(
SELECT ... FOR UPDATE) -
乐观锁:假设不冲突,通过版本号控制(CAS操作)
6: 死锁如何产生和避免?
-
产生条件:互斥、占有且等待、不可抢占、循环等待
-
避免方法:
-
按固定顺序获取锁
-
设置锁超时时间
-
使用死锁检测机制
-
尽量使用索引,减少锁定范围
-

1996

被折叠的 条评论
为什么被折叠?



