八股文_常规_mysql

164 阅读3分钟

基础

SQL语句

select * from user limit m, n:跳过前m行,返回接下来的n行

SQL分析

sql前面加explain关键字,主要观察rowstypekey

  • rows:查询时所扫描的行数
  • type:查找数据行时使用的方法,All全表扫描,range在索引树中定位到某个范围,index扫描整棵索引树
  • key:如果用到了索引 则显示对应的索引名称,没有用索引显示NULL
索引失效
  • 索引字段使用了关键字like且以%开头
  • 使用了联合索引但不符合最左前缀匹配
  • 使用is null 或者 is not null
  • 使用!= 操作符或者关键字or使用不当
  • 索引中进行了运算或函数:select name, age from user where age + 1 = 18
最左匹配原则

假设字段 (a,b,c) 建立联合索引,仅以a开头的查询能用到索引(跳过 a 直接查 b/c 索引完全失效),索引失效并不意味着需要回表,如果要查询的字段都在索引树中就不会回表

  • b>1b>=1c>1b>1 and c>1:索引无效
  • a>=1 and b=1:a b都有效(b是等值匹配)
  • a>=1 and b>1:a有效,b无效(b全局无序)
深分页处理
  • 让查询条件都在索引树中,子查询只读索引树,外层查询利用子查询得到的id 快速定位数据

  • 比如:select * from table where name = 'yupi' limit 9999990, 10可以优化为:

    select * from table 
    where
    	id >= (select id from table where name = 'yupi' limit 9999990,1) 
    	and name = 'yupi'
    order by id limit 10
    

事务

隔离级别
  • 读未提交:允许事务读取尚未提交的数据,可能产生脏读、不可重复读、幻读
  • 读已提交:仅允许读取已经提交的数据,可能产生不可重复读、幻读
  • 可重复读:确保同一事务内的多次读取结果一致
  • 串行化
MVCC机制
  • 简单来说就是select语句在执行前会生成一个 “历史事务id记录快照”,读取的时候 读已经提交的事务id 修改后的记录值。“可重复读“ 隔离级别下使用的是同一快照,所以不会看到其他事务的操作,就当其他事务没有操作过;”读已提交“ 隔离级别下,每次读取都是基于最新的“事务id记录快照”,可能会读取到 之前其他事务已经修改的数据

  • MVCC机制只存在于 “可重复读” 和 “读已提交” 两种事务隔离级别下

事务失效
  • 自己捕获了异常

  • 事务方法需要是 public 修饰的

  • 发生了内部调用,一个没有@Transactional修饰的方法去调用了其他方法,解决方案:

    // 方式一:获取当前类的代理对象
    UserService self = applicationContext.getBean(UserService.class);
    
    // 方式二:自己注入自己
    public class UserService {
        @Autowried
    	private UserService userService;
    }
    

故障排查

如何排查故障
  • 杀死某个事务:kill trx_mysql_thread_id

  • 查看客户端连接信息:show processlist,查出来的id即为线程的id

  • 查看正在执行中的事务:select * from information_schema.innodb_trx

  • 查看正在运行的锁信息:select * from information_schema.innodb_locks

如何查看慢SQL
  • 设置慢sql的阈值:set global long_query_time = 3,3表示3秒

  • 查询是否开启日志以及日志存储路径:show variables like 'slow_query_log%'

  • 查看超过多长时间会记录日志:show variables like 'long_query_time'

如何避免内存溢出
  • 使用分页查询
  • 避免一次加载大量字段

Mybatis

相关文章:juejin.cn/post/758815…

相关文章

sql练习题:sql语句练习50题(含解析)_sql练习-CSDN博客