mysql常见面试题

常见优化SQL的方法

查询时使用具体字段,而不是select *,节省资源、减少网络开销

查询结果只有一条时,使用limit 1,找到了对应的一条记录,就不会继续向下扫描了

避免在where子句中使用or连接,可分为两条查询或使用union all,使用or可能会使索引失效,从而全表扫描

避免在where子句中使用表达式与逻辑判断,那很可能会导致索引失效,扫描全表

优化like语句,不要将 % 放在关键词前,会导致索引失效

使用连接查询时,优先使用Inner jion,使用left join的话,将较小的表放左边。Inner join在两张表进行连接查询时,只保留两张表中完全匹配的结果集

优化查询的时候,可以在where和order by上建立索引,避免全表扫描

插入的数据较多的话,可以考虑使用<foreach>标签进行批量插入

需要修改的数据量大的时候,分批进行操作

索引不宜太多,一般5个以内,索引在提高查询效率的同时也降低了增删的效率

索引不适合建立在有大量重复数据的字段上,如性别,也不适合在数据量少或者更新频繁的字段上加索引,SQL优化器是根据表中数据量来进行查询优化,如发现不走索引的成本更低,很可能就放弃索引

字段类型是字符串时,where时需要用引号包裹,否则可能导致索引失效

使用explain对sql语句进行分析与优化

索引列上不要使用mysql的内置函数,否则可能导致索引失效


大表查询优化

可以从以下几个方向考虑

  1. 优化设计schema,sql语句和索引
  2. 考虑增加缓存,redis、memcache
  3. 主从复制,读写分离
  4. 太大的数据,超千万级的话,应该就需要考虑分库分表

分库分表

分库

  • 垂直分库:按照系统中的不同业务进行拆分,将他们部署在不同的服务器上
  • 水平分库:将表的数据量切分到不同的数据库服务器上,每个服务器具有相同的库和表

分表

  • 垂直分表:针对列,可以将不常用的、数据较大或者长度较长的列拆分到另外一张表
  • 水平分表:针对行,按照某种规则(如hash取模、range范围),把数据切分到多张表去

可能导致的问题

  • 事务问题:两个表在不同的数据库,那么本地事务已经无效啦,需要使用分布式事务
  • 跨库关联:分两次查询实现
  • 排序问题:分别在各个节点上得到结果后在应用程序端进行合并
  • 分页问题:节点查到对应结果后,在代码端汇聚再分页
  • 分布式ID:数据库切分后,数据库自身的主键生成机制不适用了,考虑UUID、雪花算法、redis生成ID

事务和事务的四大隔离级别

事务:由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位

事务的四大特性(ACID)

  • 原子性:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部都执行,要么都不执行。
  • 一致性:指在事务开始之前和事务结束以后,数据不会被破坏
  • 隔离性:多个事务并发访问时,事务之间是相互隔离的,一个事务不应该被其他事务干扰,多个并发事务之间要相互隔离
  • 持久性:表示事务完成提交后,该事务对数据库所作的操作更改,将持久地保存在数据库之中
    事务并发可能造成脏读、不可重复读、幻读

事务四大隔离级别

  • 读未提交
  • 读已提交
  • 可重复读(默认)
  • 串行化

隔离级别实现原理:读写锁、一致性快照读,即MVCC