1. 数据库从哪几方面进行调优?
- 数据库设计 — 三大范式、字段、表结构
- 数据库索引
- 存储过程 (模块化编程,可以提高速度)
- 分表分库 (水平分割,垂直分割)
- 主从复制、读写分离
- SQL 调优
字段优化:
- 尽量使用 TINYINT、SMALLINT、MEDIUM_INT 作为整数类型而非 INT,如果非负则加上 UNSIGNED
- VARCHAR 的长度只分配真正需要的空间
- 尽量使用整数代替字符串类型
- 单表不要有太多字段,建议在 20 以内
- 避免使用 NULL 字段,很难查询优化且占用额外索引空间
- 不建议使用 select * from t ,用具体的字段列表代替 “*”,不要返回用不到的任何字段。尽量避免向客户 端返回大数据量,若数据量过大,应该考虑相应需求是否合理
- 表与表之间通过一个冗余字段来关联,要比直接使用 JOIN 有更好的性能
- select count (*) from table;这样不带任何条件的 count 会引起全表扫描
2. 索引优化方向?
一般来说,应该在这些列上创建索引:
- 在经常需要搜索的列上,可以加快搜索的速度;
- 在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
- 在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;
- 在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
- 在经常需要排序的列(group by 或者 order by)上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
- 在经常使用在 WHERE 子句中的列上面创建索引,加快条件的判断速度。
- 总结就是:唯一、不为空、经常被查询的字段。
对于有些列不应该创建索引:
- 对于那些在查询中很少使用或者参考的列不应该创建索引。
- 对于那些只有很少数据值的列也不应该增加索引。
- 对于那些定义为 text, image 和 bit 这种数据量很大的数据类型的列不应该增加索引。
- 当修改性能远远大于检索性能时,不应该创建索引。修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。
索引失效:
在以下这些情况种,执行引擎将放弃使用索引而进行全表扫描
- 在 where 子句中使用!= 或 <> 操作符
- 在 where 子句中使用 or 来连接条件,当连接的字段有字段没有索引时,将导致所有字段的索引失效
- 在 where 子句字段进行 null 值判断,
- 在 where 子句中 like 的模糊匹配以 % 开头
- 在 where 子句中对索引进行表达式运算或函数操作
- 如果执行引擎估计使用全表扫描要比使用索引快,则不使用索引
3. mysql 问题排查都有哪些手段?怎么验证 mysql 的索引是否满足需求?
SQL 调优最常见的方式是,由自带的慢查询日志或者开源的慢查询系统定位到具体的出问题的 SQL,然后使用 explain、profile 等工具来逐步调优,最后经过测试达到效果后上线。
开启慢查询
- slow_query_log 慢查询开启状态。
- slow_query_log_file 慢查询日志存放的位置(这个目录需要 MySQL 的运行帐号的可写权限,一般设置为 MySQL 的数据存放目录)。
- long_query_time 查询超过多少秒才记录。
分析慢查询explain
在该语句之前加上 explain 再次执行,explain 会在查询上设置一个标志,当执行查询时,这个标志会使其返回关于在执行计划中每一步的信息,而不是执行该语句。
explain 通常用于查看索引是否生效, explain 执行语句返回的重要字段:
-
type:显示是搜索方式(全表扫描all或者索引扫描index)
-
key:使用的索引字段,未使用则是 null
4. 主从复制的过程?
- 在每个事务更新数据完成之前,master 在二进制日志记录这些改变。写入二进制日志完成后,master 通知存储引擎提交事务。
- Slave 将 master 的 binary log 复制到其中继日志。首先 slave 开始一个工作线程(I/O),I/O 线程在 master 上打开一个普通的连接,然后开始 binlog dump process。binlog dump process 从 master 的二进制日志中读取事件,如果已经跟上 master,它会睡眠并等待 master 产生新的事件,I/O 线程将这些事件写入中继日志。
- Sql slave thread(sql 从线程)处理该过程的最后一步,sql 线程从中继日志读取事件,并重放其中的事件而更新 slave 数据,使其与 master 中的数据一致,只要该线程与 I/O 线程保持一致,中继日志通常会位于 os 缓存中,所以中继日志的开销很小。
【Java 面试那点事】
这里致力于分享 Java 面试路上的各种知识,无论是技术还是经验,你需要的这里都有!
这里可以让你【快速了解 Java 相关知识】,并且【短时间在面试方面有跨越式提升】
面试路上,你不孤单!