索引
聚集索引:索引中键值的逻辑顺序决定了表中的物理顺序
in和exists的区别: in先执行子查询, exists先执行父查询, 然后在子查询中验证
blob和text的区别: blob存储二进制数据, text存储文本数据
- 查询条件由
or
- 如果字段类型是字符串 where时要用引号
- like通配符会使缓存失效
- 联合索引查询时的条件列不是联合索引的第一列
- 在索引上使用内置函数
- 对索引使用四则运算
- 在索引上使用bool运算
- 在索引上使用is[not] null, not in
- 左右链接查询关联字段编码不一致
索引不适合的场景
- 数据少
- 更新频繁的列
- 区分度低的列
如何优化sql
- 加索引
- 避免返回不必要的数据
- 适当分批进行
- 优化sql结构
- 分库分表
- 读写分离
分库分表
可能会遇到的问题
- 事务, 使用分布式事务
- 跨节点join, 分两次查
- 跨界点count, order by, group by及聚合函数问题, 分别查询然后合并
- id问题 考虑使用uuid
- 跨分片的排序分页问题 后台加大pagesize处理
分布式主键
- uuid
- redis
- snowflake
- zk生成唯一id
- MongoDB objectId
隔离级别 事务
- 读未提交
- 读已提交
- 可重复读
- 串行化
脏读: A,B事务交替执行A读取B未提交的数据 不可重复读: 一个事务中, 两个相同的查询读取同一条记录, 返回不同的数据 幻读: 事务A查询一个范围的结果集, 事务B往这个范围中增删数据并提交, 之后事务A再次读取, 两次结果不一致
事务的ACID
- 原子性
- 一致性
- 持久性
- 隔离性
MVCC 并发
乐观锁: 先让修改, 如果没有其他线程修改则成功 一般使用版本号或者cas实现 悲观锁: 如果有一个线程修改数据, 则拒绝其他所有线程修改
- 加锁机制 乐观/悲观锁
- 兼容性 排他/共享锁
- 粒度 表/页/行锁
- 模式 记录/gap/next-key/意向/插入意向锁