MySQL性能优化(1)

来源:互联网 发布:军事小说 知乎 编辑:程序博客网 时间:2024/05/21 08:51

我们的数据层实现都是最精简的吗?
从以往的经验来看,一个合理的数据存取实现和一个拙劣的实现相比,在性能方面的差异经常会超
出一个甚至几个数量级。我们先来分析一个非常简单且经常会遇到类似情况的示例:
在我们的示例网站系统中,现在要实现每个用户查看各自相册列表(假设每个列表显示 10 张相片)
的时候,能够在相片名称后面显示该相片的留言数量。这个需求大家认为应该如何实现呢?我想 90%的开
发开发工程师会通过如下两步来实现该需求:
1、通过“SELECT id,subject,url FROM photo WHERE user_id = ? limit 10” 得到第一页的相片
相关信息;
2、通过第 1 步结果集中的 10 个相片 id 循环运行十次“SELECT COUNT(*) FROM photo_comment
WHERE photh_id = ?” 来得到每张相册的回复数量然后再瓶装展现对象。
此外可能还有部分人想到了如下的方案:
1、和上面完全一样的操作步骤;
2、通过程序拼装上面得到的 10 个 photo 的 id,再通过 in 查询“SELECT photo_id,count(*) FROM
photo_comment WHERE photo_id in (?) GROUP BY photo_id” 一次得到 10 个 photo 的所有回复数量,
再组装两个结果集得到展现对象。
我们来对以上两个方案做一下简单的比较:
1、从 MySQL 执行的 SQL 数量来看 ,第一种解决方案为 11(1+10=11)条 SQL 语句,第二种解决方案
为 2 条 SQL 语句(1+1);
2、从应用程序与数据库交互来看,第一种为 11 次,第二种为 2 次;
3、从数据库的 IO 操作来看,简单假设每次 SQL 为 1 个 IO,第一种最少 11 次 IO,第二种小于等于 11
次 IO,而且只有当数据非常之离散的情况下才会需要 11 次;
4、从数据库处理的查询复杂度来看,第一种为两类很简单的查询,第二种有一条 SQL 语句有 GROUP
BY 操作,比第一种解决方案增加了了排序分组操作;
5、从应用程序结果集处理来看,第一种11 次结果集的处理,第二中2 次结果集的处理,但是第二种
解决方案中第二词结果处理数量是第一次的 10 倍;
6、从应用程序数据处理来看,第二种比第一种多了一个拼装 photo_id 的过程。
我们先从以上 6 点来做一个性能消耗的分析:
1、由于 MySQL 对客户端每次提交的 SQL 不管是相同还是不同,都需要进行完全解析,这个动作主要
消耗的资源是数据库主机的 CPU,那么这里第一种方案和第二种方案消耗 CPU 的比例是 11:2。SQL 语句的
解析动作在整个 SQL 语句执行过程中的整体消耗的 CPU 比例是较多的;
2、应用程序与数据库交互所消耗的资源基本上都在网络方面,同样也是 11:2;
3、数据库 IO 操作资源消耗为小于或者等于 1:1;
4、第二种解决方案需要比第一种多消耗内存资源进行排序分组操作,由于数据量不大,多出的消耗
在语句整体消耗中占用比例会比较小,大概不会超过 20%,大家可以针对性测试;
5、结果集处理次数也为 11:2,但是第二中解决方案第二次处理数量较大,整体来说两次的性能消
耗区别不大;
6、应用程序数据处理方面所多出的这个 photo_id 的拼装所消耗的资源是非常小的,甚至比应用程
序与 MySQL 做一次简单的交互所消耗的资源还要少。
综合上面的这 6 点比较,我们可以很容易得出结论,从整体资源消耗来看,第二中方案会远远优于
第一种解决方案。而在实际开发过程中,我们的程序员却很少选用。主要原因其实有两个,一个是第二
种方案在程序代码实现方面可能会比第一种方案略为复杂,尤其是在当前编程环境中面向对象思想的普
及,开发工程师可能会更习惯于以对象为中心的思考方式来解决问题。还有一个原因就是我们的程序员
可能对SQL语句的使用并不是特别的熟悉,并不一定能够想到第二条SQL 语句所实现的功能。对于第一个
原因,我们可能只能通过加强开发工程师的性能优化意识来让大家能够自觉纠正,而第二个原因的解决
就正是需要我们出马的时候了。 SQL 语句正是我们的专长,定期对开发工程师进行一些相应的数据库知
识包括 SQL 语句方面的优化培训,可能会给大家带来意想不到的收获的