当前位置: > 数据库 > MySQL >

mysql调优及架构设计心得一二

时间:2014-12-14 13:57来源:linux.it.net.cn 作者:IT

谈起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各参数

 

Id

Query optimizer执行计划的序列号

Select_type

使用的查询类型: dependent subquery 子查询中的第一个select 依赖外部查询结果集,dependent union 子查询中的union依赖外部查询结果集,primary子查询中的最外层查询,simple 除子查询和union之外的其他查询,subquery 子查询内层的第一个select不依赖外部查询结果,uncacheable subquery无法缓存的子查询,union union语句中的第二个select开始后后的所有查询(第一个为primary),union result  union中的合并结果

Table

显示这一步所访问的表

Type

对表的访问方式:all 全表扫描,const 读常量,实际上只需要读一次,eq_ref 最多只会有一条匹配,通过主键索引或唯一键索引访问, index 全索引扫描,index_merge 查询时候同时使用两个以上索引,然后对索引merge之后再读取表数据,index_subquery 子查询的返回结果是一个索引或索引组合,rang 索引范围扫描,ref join语句中被驱动表索引引用查询,ref_or_null 增加了ref方式的空值查询,sysytem 系统表 只有一行数据,uniquer_subquery 子查询返回结果为主键或唯一索引

Possible_keys

该查询可用的索引

Key

实际使用的索引

Key_Len

被使用索引的索引长度

Ref

列出是通过常量还是字段来过滤

Rows

估算的结果集条数

Extra

额外细节: using filesort order by操作无法使用索引完成排序,using index 所需数据在index可全部获的,using where 不是读取全部信息或者不是通过索引就可以获取所有需要数据

 




(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容