Mysql 性能优化真实案例(面试可用)
Posted memory_cood
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql 性能优化真实案例(面试可用)相关的知识,希望对你有一定的参考价值。
项目背景
系统包含多个直播平台数据斗鱼,虎牙,QQ音乐等多个业务的数据,通过数据分析重组计算并按照一定数据格式返回给前端以多种数据表格形式展示包括直线图,柱状图,饼状图,表格等。数据权限和操作权限按照用户分配角色,角色分配权限的方式设计。数据上传下载利用阿里巴巴插件进行快速导入,导出。我主要负责项目优化对百万数据量的导入、数据清洗、查询、分析、统计。
优化一 选择更合适的存储引擎
针对这个项目是读多写少场景,我这里把原来mysql 默认的搜索引擎INNODB 改为 MYISAM 。
INNODB 和 MYISAM 使用场景
很多人在设计数据库的时候往往忘记了一个东西—存储引擎。一般我们常听见的有 MYISAM 和 INNODB 两种。
INNODB : 被MYSQL设置为默认存储引擎肯定是它更加适用更多场景,它这对写操作比较友好,锁粒度更小,支持行锁,而且支持事务(这一点我感觉是它更加常用的地方,因为很多系统都需要事务的支持的)
MYISAM:它的特点其实刚好和INNODB是相反的。它对读操作友好,锁粒度大,只能表锁,而且不支持事务。
结论
所以我改用MYISAM作为这个系统的存储引擎应该大家能够理解了把。由于这个系统是读多写少,几乎是不写入,只有一个批量的导入数据的,其他都是读,也不会改数据,所以它不用事务,不用行锁,只要查询速度快。刚好满足MYISAM的特性。
优化二 重构数据库表
该系统包括很多直播平台的数据(斗鱼、熊猫、YY、虎牙等)。这里一开始是用一张表存储所有数据,后来数据量大了,大约是百万级别的时候,发现项目的查询效率明显慢了很多。这里我采用分表的形式,用平台作为区分进行了分表。这里就好比查同样的东西。你在一千万里面的数据量里面查,我在一百万里面的数据里面查。因为我提前做了一次对数据的区分。
优化三 索引的使用
如果单独讲索引,好几篇博客都讲不完的,所以我在这里我就说一下我在项目中是如何使用索引,和避免索引失效,导致查询全表的。一般我们设计表的时候都有一个主键索引,而往往我们就用这个索引。这里我用的主键是平台的主播的ID作为主键索引,因为每个平台已经被我区别开了,所以不存在平台之间相同ID,然后我会在经常查询的几张表中,建立一些组合索引经常用到的列,比如:用户昵称、平台、日期等。
- 首先满足查询做小原则:永远只查询需要的列,不需要的列不要查出来,特别对 select * from tablename 这种查询如果你带主键查询,尽管用来索引查询,但很大程度会造成回表(如果不懂回表,请在评论区回复,我下期单独说,或者百度把)。
- 先做子查询,再做连表查询,不直接连表查询。这个是很多人的习惯,喜欢把相关联的几张表先join 连接起来,然后把条件放在where 后面,这个样的做法会使内联表后数据就变得臃肿了,这时候再进行条件查询和分组就太吃亏了,于是我们可以先对单表进行条件处理,再进行连表查询,只不过这个方案只是用了子查询而没有内联查询了
- 避免索引失效,查询全表,我不知道大家知不知道MYSQL的索引左匹配原则,意思就是,如果你有两个索引(a,b) ,然后你的查询条件这样写 where c>0 and a=’?’ and b=‘1’,类似这样的场景,就会使你的索引失效,进而扫描全表,这个是灾难性的查询。所以在开发中一定要注意。还有考虑在where及order by 涉及的列上创建索引量避免在where字句中对字段进行null值的判断。否则将会导致引擎放弃使用索引而进行全表扫描。
这里有张图,大家可以借鉴一下
好了,上面就是我在项目里面的优化过程,下面来谈几个面试常见的问题把
问题一 MYSQL为什么用B+树作为索引
Mysql选用B+树这种数据结构作为索引,可以提高查询索引时的磁盘IO效率,并且可以提高范围查询的效率,并且B+树里的元素也是有序的。一般使用磁盘I/O次数评价索引结构的优劣。预读:磁盘一般会顺序向后读取一定长度的数据(页的整数倍)放入内存局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用B+Tree节点的大小设为等于一个页,每次新建节点直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,就实现了一个节点的载入只需一次I/OB+Tree的度d一般会超过100,因此h非常小(一般为3到5之间)。还有另外一种答案:它的非叶子节点是不存数据的,只有叶子节点才存数据,非叶子节点存的是数据的索引值,它的树的高度足够低。
为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+Tree组织的一个索引结构),必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。
自增ID可以保证每次插入时B+索引是从右边扩展的,可以避免B+树和频繁合并和分裂(对比使用UUID)。如果使用字符串主键和随机主键,会使得数据随机插入,效率比较差。
码字不易,给个赞咯
下面是我得公众号二维码,扫一扫可能有惊喜哦哈哈
以上是关于Mysql 性能优化真实案例(面试可用)的主要内容,如果未能解决你的问题,请参考以下文章