谈起mysql的调优,很多人第一反应就是query语句的优化,这诚然不错,但已经偏颇了,实际工作中mysql的优化一半以上效果应该是在业务和架构设计上,尤其是数据库架构的设计优化,query语句的优化大概只占三分之一,剩下一些系统性能的调整。所以根据业务需求设计调整出一个良好的架构是重中之重。 架构的设计包括程序的流程和数据存储方式,我们着重看看数据存储相关的表设计,有几个简单的原则是需要在设计之初就想好的、 1, 二进制数据和超大文本数据(包括超过255字节的text数据),队列数据,不适合存储在数据库中,数据库处理这些东西会耗费相当多的资源。 2,系统配置信息,访问频繁,变更很少,活跃用户基本信息,个性化信息,准实时统计信息这些都可以使用cache存储。 4,适度冗余,适度的重复字段以减少join几率,join的表越多,造成的阻塞越大,性能影响越明显。 5,适度垂直拆分,将不太使用的,查询不频繁的,数据较大的字段与热门字段分表存放,热门字段和冷门字段分表存放。 6,大表拆分将 单独信息不和表其他信息产生关联,变化相对较小的数据与访问频率较高信息量比较少进行拆分。 7,避免过度理想化的用户体验,使大量资源耗费在非核心业务 分表的目的是为了节省数据库的io资源,即使你query时候不选取字段,都常常会在排序,连接的时候mysql需要将所有字段取出来然后再操作,这耗费了相当一部分的io资源,这一点需要特别的注意 架构的设计,是需要在业务要求上做出优化调整的,很多人恰恰忽视了这个重要的原则。举个例子来说明,现在有一个论坛系统,根据论坛系统简单功能需要有用户,用户组,组讨论区的基本功能,很多时候如果你根据直觉上来就把库分为用户表,分组表,分组关系表,帖子表四张表。那会造成系统资源的很大浪费,比较好的方案是将用户表分为用户表和用户属性表,将帖子表分为帖子列表和帖子内容表。为什么这么分?因为一个论坛访问最大的是帖子目录,这目录里需要用户的详细信息体现嘛?不需要,大概只要个用户名就够了,而帖子列表也不需要帖子的内容,只需要个标题就够了。如果再在帖子列表的中加上一个亢余的字段放上用户名称,你每次的页面查询是不是只需要取一个表内容的就够了?省掉很多的join操作,而且这个query无论怎么排序查找都不会需要不相关的内容如用户邮件地址,登陆日期。如帖子内容这些东西取出来而耗费系统io资源。如果你担心需要这些不常用的内容时候,反而增加了操作次数,那么完全没有必要,因为1,最常用的最频繁的query操作你节省的资源是以乘数倍增了,不常用的资源需要的时候去连接操作取出来并不会耗费很多资源,这两个的差数是很大的。所以query优化里有一个原则是优化最需要优化的语句就是这个意思 。2,因为两个表都是一一对应的关系,过滤性非常的高,取这些内容并不会耗费太多资源。 架构的设计优化还包括了数据的切分整合,数据库引擎的优化,Cache的应用,事务优化等等内容,这里就不一一详述了。 mysql优化最花费时间的,也最容易立即看到效果的是query语句的优化,这里也有一些简单的原则,
1,优化高并发低消耗的sql语句比低并发高消耗的sql语句效果更大。 2,以小结果集来循环大结果集。 3,where条件并不是越多越好 ,即使加了索引.根据搜索条件的字段的长度,越大的字段,读取索引就需要读取更多量的数据。 4,,join越多的表,读取时候的锁定资源越多,阻塞的其他线程也越多,大并发的时候性能下降越厉害。 5,只取出需要的字段。 6,mysql中目前执行子查询的效率很差。 7, 索引创建的条件,较频繁做为查询条件的字段适合做索引,唯一性差的不适合做索引,更新非常频繁的字段不适合做索引
实际操作过程中除了这些简单的原则外,还有很多需要一一琢磨的地方,那么学会分析使用explain和profiling工具就很重要。explain可以将mysql查询优化的相关过程详细的显示出来,profiling可以将语句耗费的io和cpu资源显示出来,query语句优化的第一步就是要找到该语句消耗瓶颈在cpu还是在io。然后才有的放矢。适当的时候开启慢查询日志,也能帮助我们找到资源瓶颈。query优化的时候影响行数,使用的索引都是我们重点查看的内容,因为相关举例需要大量贴图,这里就不一一详述,网上有很多的教程可以学习研究,我在这里贴出来explain的一些相关参数细节来结束本篇。
explain各参数
(责任编辑:IT) |