数据库优化方案
一、关系型数据库在项目中通常会遇到哪些问题或者说是瓶颈呢??
查询每个班每个学生的每个课程的成绩
这里简单的举例如下:
1.高并发读写操作数据库
比如我们的双十一购物场景 --> 解决:集群、分布式
2.海量数据的高效率读写
比如在一张包含海量数据的表中查询,插入速度会很慢(ex:淘宝,京东等商城项目中的商品表) --> 解决:分表,分库
3.高扩展性和可用性
在基于web的结构(即浏览器/服务器)当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库却没有办法简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移.
二、那么关系型数据库如何优化??
1.分析SQL,优化SQL语句
查看SQL语句执行效率
explain select * from s1;
查看执行时间
show variables like "%pro%";
set profiling = 1;
show profiles;
2.单机模式
- 表结构
三种规则
1:原子性 列不可分割 【日期】(2020-20-12 14:30)
2:记录具有唯一标识 通常通过主键实现
3:表中尽量不要有冗余数据,能够通过其他表推导出来的数据不要单独设置字段
数量 单价 总和
- 引擎
mysql常用的三种存储引擎 myisam,innodb,memory
innodb:支持事务 行级锁 外键
myisam:支持表级所
memory:内存级别的引擎,读取速度很快
根据业务场景选择合适的存储引擎
- 索引
索引简单介绍
索引的功能:加速查找
索引的分类
主键索引(primary key) 除了索引的功能还有约束功能(unique+not null)
唯一索引(unique) 除了索引功能,还有唯一约束(unique)
普通索引(index) 只有索引功能
联合索引:
联合主键索引:primary key(id,name)
联合唯一索引:unique(id,name)
联合普通索引:index(id,name)
全文索引(fulltext)
但其实对于全文搜索,我们并不会使用MySQL自带的该索引,而是会选择第三方软件如Sphinx,专门来做全文搜索
索引的主要功能是提高查询的效率
并不是说我们创建了索引就一定会加快查询速度,若想利用索引达到预想的提高查询速度的效果,我们在添加索引时必须遵循以下问题.不
1.查询的条件必须是已经创建索引的字段
select * from stu where name = '朱利轩'
2.范围问题,或者说条件不明确,条件中出现:> < >= <= != between and like等,若范围过大,照样不能提高查询效率,毕竟数据量的问题.
对于like 若是'%XXX"开头为%,即使是索引,也没用了,可以采用 'XXX%'
select * from stu where name like '王%';
3.尽量选择区分度高的列作为索引
student sex性别
4.索引列不能在条件中参与计算,保持列干净
5.and /or
条件1 and 条件2:所有条件都成立才算成立,但凡要有一个条件不成立则最终结果不成立
条件1 or 条件2:只要有一个条件成立则最终结果就成立
and:对于多个连续的and,mysql会按照联合索引,从左到右的顺序找一个区分度高的索引字段(这样便可以快速锁定很小的范围),加速查询.
or: 对于连续多个or,mysql会按照条件的顺序,从左到右依次判断
6.最左前匹配原则
组合索引最左前匹配原则
如果组合索引为:(name,email)
name and email ---命中索引
name --命中索引
email 未命中索引
7.类型不一致
如果列是字符串类型,传入的条件是必须使用引号引起了,不然无法命中索引
8.若排序条件为索引,则select字段也必须是索引字段,否则无法命中
其他注意事项
- 避免使用select *
- 使用count(*)
- 创建表时尽量使用 char 代替 varchar
- 表的字段顺序固定长度的字段优先
- 组合索引代替多个单列索引(由于mysql中每次只能使用一个索引,所以经常使用多个条件查询时更适合使用组合索引)
- 尽量使用短索引
- 使用连接(JOIN)来代替子查询(Sub-Queries)
- 连表时注意条件类型需一致
- 索引散列值(重复少)不适合建索引,例:性别不适合
总结: 满足以下条件的字段,才应该创建索引.
a: 肯定在where条件经常使用 或者经常用来排序 order by后面的字段
b: 该字段的内容不是唯一的几个值(例如:sex)
c: 字段内容不是频繁变化.
- 分表(垂直分表和水平分表)
水平分表
如果一张表中数据量巨大时,我们要经常查询。则可以按照合适的策略拆分为多张小表。尽量在单张表中查询,减少扫描次数,增加查询效率。如果拆分不好,经常组合(union)查询,还不如不拆分.
分表策略:
1.按时间分表:这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。
2.按区间范围分表:一般在有严格的自增id需求上,如按照user_id水平分表:
table_1 user_id从1~100w
table_2 user_id从100W+1~200w
table_3 user_id从200W+1~300w
3.hash分表:通过一个原始目标的ID或者名称通过一定的hash算法计算出数据存储表的表名,然后访问相应的表。
最简单hash算法: T_user + Id%100+1 复杂hash算法:...
垂直分表
如果一张表某个字段,信息量大且不经常查询,则可以考虑把这些字段,单独的放入到另一张表中,用外键关联。如果硬是要查询,就是用跨表查询(join)
分区分表(了解,自己研究)
3.多机模式
- 读写分离(集群,让多台服务器提供服务)
单机处理到达瓶颈的时候,你就把单机复制几份,这样就构成了一个“集群”。集群中每台服务器就叫做这个集群的一个“节点”,所有节点构成了一个集群。每个节点都提供相同的服务,那么这样系统的处理能力就相当于提升了好几倍
- 分布式(把不同业务分给不同的集群处理)
集群结构的好处就是系统扩展非常容易。如果随着你们系统业务的发展,当前的系统又支撑不住了,那么给这个集群再增加节点就行了。但是,当你的业务发展到一定程度的时候,你会发现一个问题——无论怎么增加节点,貌似整个集群性能的提升效果并不明显了。这时候,你就需要使用微服务结构了。
4.缓存机制
- redis 不讲
附录
想详细了解,可以点击下面的网址进行学习
https://blog.csdn.net/qq_38225558/article/details/87896026
https://zhuanlan.zhihu.com/p/27871998
https://www.zhihu.com/question/20004877