数据库调优

105 阅读4分钟

数据库调优

调优目标

如何定位需要调优的问题

调优的维度和步骤

具体的调优层面

优化mysql的服务器

优化数据结构

  • 调优目标
  1. 尽可能的节省系统的资源,内存,cpu,可以让系统提供更大载荷发的服务。就是吞吐量调到最大。

  2. 对数据库的结构和参数调整,提高用户操作的响应速度。

  3. 减少系统的瓶颈,提高mysql整体性能。

总结:加大吞吐量,提高响应速度,减少系统瓶颈。

  • 如何定位需要调优的问题
  1. 用户反馈

  2. 日志分析(mysql日志分析)

  3. 服务器资源监控系统来进行监控

  4. 数据库内部状态监控

  5. 其他比如对锁,事物等等进行监控

  • 调优的维度和步骤

首先要明确:正常来说调优的对象是数据库系统(DBS),对开发人员来说,维护好DBMS就可以了

维护DBMS 数据库管理系统,就不能单纯的从sql语句上面来优化,还包括数据库的部署配置,架构设计等等。

步骤:

数据库选型 mysql oracle sqlServer redis

通过业务场景:对事务的要求比较高,安全性较高就可以选择商用数据库oracle sqlserver

oracle单表存储上亿条数据,都是没有问题的,如果设计的合理,都不用分库分表

开源的mysql,可以选择存储引擎,对事务有要求innodb,对事务没有要求 myisam 这个更快

搜索类的系统,缓存型数据库 redis es mysql+redis+es是和可以组合

优化库的架构 主从复制 表的结构

库的优化

主从复制

读写分离

读一台数据库

写一台数据库

读写数据库通过技术手段mycat进行同步

数据分片(针对500万以上级别数据,进行分片)电商 互联网高并发的应用

把数据分库分表

分库 不讲

分表:

冷热数据分离 就可以减少表的宽度 mysql最多4096列

每一行的数据大小是不能超过65535字节的

热数据(字段操作比较频繁的)

冷数据(字段操作不平凡)

增加中间表

如果两张表要经常关联查询,而又不能反范式的时候,

可以创建中间表,就是将经常要查询的数据插入到中间表中,

然后将原来的联合查询,改成只查询中间表。

举例:学生信息表,班级表

现在有一个模块需要经常查询 学生姓名,班级名称,班级班长的学生信息

就可以创建一个 temp_student 中间表(视图),存储学生姓名,班级名次,班长名字的信息

表的优化:

三大范式+反范式 如果多表关联查询比较多,就尝试反范式 单表查询--在应用层组合

优化逻辑查询

比如索引index的优化(重点是要知道如何使用索引)

使用缓存机制 比如使用缓存数据库redis搭配使用

-- 查看员工中名字以WAR开头的人都有谁?
-- 效率高于第二个
select * from emp e where e.ename like "war%";
-- where子句中用了库函数(里面有逻辑算法)
select * from emp e where substring(ename,1,3) = 'war';
-- 查看 20 号部门和30号部门的员工有哪些?
-- 效率高于第二个
select * from emp e where e.deptno = 20 or e.deptno = 30; 
select * from emp e where e.deptno in(20,30); 
-- 关联的时候,要小表驱动大表  emp 和dept   用dept作为主表 去驱动emp
-- 插入数据优化
 /*
  影响插入数据速度的因素:
      有索引,唯一性校验,一次性插入的条数
      如果有大量的数据可以在新增数据之前先禁用,新增完后再开启
 */   
 -- 在插入之前可以禁用索引
 alter table emp disable keys;  -- 禁用
 alter table emp enable keys;   -- 启用
 -- 可以禁用唯一检查
 set unique_checks = 0;  -- 禁用
 set unique_checks = 1;  -- 开启
 -- 批量插入 
 insert emp(ename) values("Andy")
 insert emp(ename) values("Andy")
 insert emp(ename) values("Andy"),("Andy"),("Andy"),("Andy"),("Andy"),("Andy");
 -- 禁用外键检查
 set foreign_key_checks = 0; -- 禁用
 set foreign_key_checks = 1; -- 开启
 -- 禁用自动提交(mysql里面默认是开启的)
 set autocommit = 0;  -- 禁用  一次性的,只要你关闭连接,从新再连,就又会默认开启,如果要长久关闭,就可以去修改改配置文件
 set autocommit = 1;  -- 开启
 
 show variables like 'autocommit';
 -- 插入一条数据,然后关闭连接,从新再连,查看数据是否还存在
 insert emp(empno) values(88888);

select * from emp order by empno desc;