当Mysql单表记录数过大时,增删改查的性能就会急剧下降,所以我们需要对其进行优化增加用户的体验性。
字段
尽量精准使用,例如说不要一上来就用int,尽量使用smallint、unsigned等等
尽量使用varchar ,它只分配真正需要的空间
日期类型的时候尽量使用timestamp,避免使用datetime
不要习惯性的让字段可以为null,难以优化引用可空列查询,它会使索引、索引统计和值更加复杂,可空列需要更多的存储空间,还需要mysql内部进行特殊处理。可空列被索引后,每条记录都需要一个额外的字节
减少请求的数据量
只返回必要的列:避免select *这种写法,虽然直接写成select * 代码的可利用性增强
只返回必要的行:使用 where 语句进行查询过滤,有时候也需要使用 limit 语句来限制返回的数据
缓存一直请求的数据 :这样命中后就可以直接返回了,不用再次查询
索引
不要一昧的建立很多索引,因为你在更新数据的同时也要更新索引,比较麻烦,所以,在一个经常要修改、增加、删除的表,我感觉最好不要建;还有啊 ,一些 值分布很稀少的字段也别建立索引了,例如 sex、
考虑在经常 where 和 order by 、between and 中 涉及的列建立索引,感觉范围查询的话B+索引真的会快很多耶。
别在where子句中对字段进行NULL判断,这样会导致没有使用索引,直接是全表扫描;尽量保证语句最简,例如说 select * from account where id + 1 = 5,虽然查询效果和id = 4一样,但这个查询退化成了全表扫描,还有 !=,<>也是一样,这样都会退化成全表扫描的,我们可以使用explain来查看执行情况。
多列索引比使用多个单列索引性能更好: 例如,SELECT film_id, actor_ id FROM sakila.film_actor
WhERE actor_id = 1 AND film_id = 1;这时候我们建立一个多列索引效果要好一点
索引列的顺序真的非常重要: 让选择性最强的索引列放在前面,索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,查询效率也越高。例如COUNT(DISTINCT staff_id)/COUNT(*)
where子句中不要使用 or ,这样就算你在这两个字段上建立了多列索引也不会用的;还有 %也是一样,那么问题来了,如果是模糊查询的话,该怎么优化呢?......待续,
字符字段可以建前缀索引,不要整个建索引,这样开销真的很大,还有,可以联合hash将前缀映射成一个hash值,存储hash值,这样会更快一些
查询SQL
拆分 : sql语句尽可能的要简单,大语句拆分成小语句,减少锁时间。因为一个大查询如果一次性执行的话,可能一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但重要的查询
or 改成 in : or 的效率是n级别的,in的效率是log(n)级别的
*少用 join ,将多表联合分解成对每一个表进行一次单表查询,然后将结果在应用程序中进行关联,关于这个我看过别人的一个视频,也是这样说的,别用外键,由程序进行约束;还有就是尽量避免多表联合查询,在高并发的环境下,联合查询确实效率要低很多,虽然这会导致数据冗余.......我也不清楚实际企业中怎么用。
对于连续数据,使用between and 不用 in
拆分
在数据量真的过大的时候可以采取的方法,一般情况下可以不用这样,以整型为主的表在千万级以下,字符串为主的在五百万以下的应该没有什么问题(我之前试了一下,电脑太渣,)
----- 垂直分区
垂直切分是将一张表按列切分成多个表,通常是按照列的关系密集程度进行切分。也可以利用垂直切分将经常被使用的列和不经常被使用的列切分到不同的表中。
也可以在数据库的层面使用垂直切分,它按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商品数据库 payDB、用户数据库 userBD 等。
缺点:
引起多表的join(我自己感觉这点真的很不好)
依然存在单表数据量过大的问题
事务处理复杂
----- 水平分区
它是将同一个表中的记录拆分到多个结构相同的表中。当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。感觉比上一种要好
缺点:
分片事务一致性难以解决
数据维护量大
作者:维特无忧堡
链接:https://www.jianshu.com/p/9302e72d5209
共同学习,写下你的评论
评论加载中...
作者其他优质文章