MySQL的问题首先有很多都是会结合几张表信息然后出题的笔试,其中会涉及到表连接查询,建议大家也可以去LeetCode刷一刷题,可能小伙伴大多数会在上面刷一些算法,但其实有很多分类的呀
然后被问到频率最高的就是索引啦
- 了解索引吗?
- 首先索引是帮助MySQL高效获取数据的排好序的数据结构,
- MySQL的索引底层是B+tree,默认一个节点16kb
- 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
- 叶子节点包含所有索引字段
- 叶子节点之间用指针链接,提高区间访问的性能
不了解B+树的同学看这里,
- 首先你知道二叉树吧?就是一个根节点包含左右两个节点,
- 然后红黑树就是动态维持平衡的二叉树,也就是插入一个节点的时候小的放左边,大的放右边
- 然后B-tree是红黑树的一个升级,横向增加多个节点
- 叶子节点具有相同的深度,叶节点的指针为空
- 所有索引元素不重复
- 节点中数据索引从左到右递增排列 横向存储更多的元素
- 最后B+树比B树升级的地方在于:只有叶子节点才会存储data,而非叶子节点存储的索引是冗余的,且叶子节点间用指针链接,更高效的范围查找
然后扩展到单列索引和联合索引。
- 如果(A,B,C)联合索引,查询(B,C)时会不会走索引?
- 不会,遵循最左匹配原则,从左往右依次比较大小
- 最左前缀匹配原则,MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如 a=3 and b=4 and c>5 and d=6,如果建立(a,b,c,d)顺序的索引,d是无法使用索引的,如果建立(a,b,d,c)的索引则都可以使用到,a、b、d的顺序可以任意调整。=和in可以乱序,比如 a=1 and b=2 and c=3 建立(a,b,c)索引可以任意顺序,MySQL的查询优化器会帮你优化成索引可以识别的形式。
- 对于千万级的数据怎么优化?(我确实没有这方面的经验,呜呜呜~)
- 表的合理化设计(符合3F)
- 添加适当索引(普通索引、主键索引、唯一索引、全文索引)
- 分表技术(水平分割、垂直分割)
- 读写(写:update、delete、add)分离
- 存储过程【模块化编程、可以提高速度】
- 对MySQL配置优化【配置最大并发数my.ini,调整缓存大小】
- MySQL服务器硬件升级
- 定时的去清除不需要的数据,定时进行碎片整理(MyISAM)
表设计:
- 如果你设计一套权限系统会怎么进行设计?
- 如果你设计一套抢购系统怎样保证库存不超卖?
- 乐观锁(数据库加版本号)
- 可以利用Redis缓存库存数量字段,当库存为0的时候屏蔽数据库请求
- 可参考博客高并发解决(如何设计一个秒杀系统)
关于SQL优化问题
可以用explain关键字查询,面试中我答不出来这么多,但是为了加强理解整理一下
- 可以在正常执行的SQL语句之前直接加上explain关键字,然后执行
- expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
- 概要描述:
- id:选择标识符
- 相当于SQL执行的顺序的标识,id标识SQL执行的优先级,id相同时,从上到下顺序执行。
- select_type:表示查询的类型。
- (1) SIMPLE(简单SELECT,不使用UNION或子查询等)
- (2) PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
- (3) UNION(UNION中的第二个或后面的SELECT语句)
- (4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
- (5) UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)
- (6) SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)
- (7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)
- (8) DERIVED(派生表的SELECT, FROM子句的子查询)
- (9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)
- table:输出结果集的表(表的名称)
- partitions:匹配的分区
- type:表示表的连接类型
- ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
- index: Full Index Scan,index与ALL区别为index类型只遍历索引树
- range:只检索给定范围的行,使用一个索引来选择行
- ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
- eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
- const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
- NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
- possible_keys:表示查询时,可能使用的索引
- key:表示实际使用的索引
- key_len:索引字段的长度
- ref:列与索引的比较
- rows:扫描出的行数(估算的行数)
- filtered:按表条件过滤的行百分比
- Extra:执行情况的描述和说明
更详细可以看看MySQL Explain详解
MySQL大数据量查询的SQL优化可以参考一下这篇,
锁
- 乐观锁(多读场景,提高吞吐量)
- 总是假设最好的情况,每次拿数据的时候都认为别人不会修改,所以不会上锁,但更新的时候会判断在此期间有没有人修改过这个数据,可以使用版本号和CAS机制实现
- 悲观锁(多写场景,减少冲突)
- 总是假设最坏的情况,每次拿数据的时候都认为别人会修改,所以在每次拿数据的时候都会上锁,这样别人取数据的时候就会阻塞。
- 比如行锁、表锁、读锁、写锁等,都是在操作之前先上锁。
- synchronized和ReentrantLock都是基于这种思想
陆续更新中。。。