`
BradyZhu
  • 浏览: 246846 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

【总结】MySQL性能优化

 
阅读更多
1,MySQL基础
- MySQL物理文件组成
- MySQL逻辑架构
- MySQL自带工具
2,MySQL存储引擎
- MyISAM
- Innodb
- NDBCluster
3,MySQL性能优化
- 硬件层优化
- OS层优化
- MySQL层优化分析
- 系统架构及实现对性能的影响
-不适合放在数据库存放
-二进制多媒体数据
-流水队列数据
-大文本数据
-适合缓存
-系统各种配置规则数据
-活跃用户的基本信息数据
-活跃用户的个性化定制信息数据
-准实时的统计信息数据
-其他一些访问频繁但变更较少的数据
-常见设计问题
-Cache系统不合理利用导致Cache命中率低下造成数据库访问量的增加,同时也浪费了Cache系统的硬件资源投入
-过度依赖面向对象思想,对系统
-可扩展性的过度追求,促使系统设计的时候将对象拆得过于离散,造成系统中大量的复杂Join语句,而MySQL Server 在各数据库系统中的主要优势在于处理简单逻辑的查询,这与其锁定的机制也有较大关系
-对数据库的过度依赖,将大量更适合存放于文件系统中的数据存入了数据库中,造成数据库资源的浪费,影响到系统的整体性能,如各种日志信息
-过度理想化系统的用户体验,使大量非核心业务消耗过多的资源,如大量不需要实时更新的数据做了实时统计计
-归结为过渡依赖嵌套循环的使用或者说是过渡弱化SQL语句的功能造成性能消耗过多
-Query语句对性能的影响
- 两表分页排序查询:用子查询,得到主表的排序分页结果,在Join第二张表
- Schema设计对性能的影响
-大字段拆分
-数据冗余
- 硬件环境对性能的影响
-OLTP 应用系统(on-line transaction processing:并发量大,整体数据量比较多,但每次访问的数据比较少,且访问的数据比较离散,活跃数据占总体数据的比例不是太大
-大内存容量来尽可能多的将活跃数据cache到内存中
-虽然IO访问非常频繁,但是每次访问的数据量较少且很离散,那么我们对磁盘存储的要求是IOPS现要很好,吞吐量是次要因素
-并发量很高,CPU每秒所要处理的请求自然也就很多,所以CPU处理能力需要比较强劲
-虽然与客户端的每次交互的数据量并不是特别大,但是网络交互非常频繁,所以主机与客户端交互网络设备对流量能力也要求不能太弱
-OLAP 应用系统(On-Line Analytical Processing:数据量非常大,并发访问不多,但每次访问所需要检索的数据量都比较多,而且数据访问相对较为集中,没有太明显的活跃数据概念
-数据量非常大,所以磁盘存储系统的单位容量需要尽量大一些
-单次访问数据量较大,而且访问数据比较集中,那么对IO 系统的性能要求是需要有尽可能大的每秒IO吞吐量,所以应该选用每秒吞吐量尽可能大的磁盘
-虽然IO 性能要求也比较高,但是并发请求较少,所以CPU 处理能力较难成为性能瓶颈,所以CPU处理能力没有太苛刻的要求
-虽然每次请求的访问量很大,但是执行过程中的数据大都不会返回给客户端,最终返回给客户端的数据量都较小,所以和客户端交互的网络设备要求并不是太高
-OLAP 系统由于其每次运算过程较长,可以很好的并行化,所以一般的OLAP 系统都是由多台主机构成的一个集群,而集群中主机与主机之间的数据交互量一般来说都是非常大的,所以在集群中主机之间的网络设备要求很高
- MySQL层优化
- MySQL数据库锁
- 行级锁定(row-level)
- Innodb
- 共享锁(意向)
- 排他锁(意向)
- 原理:“NEXT-KEY locking”(间隙锁
-当Query无法利用索引的时候,Innodb会放弃使用行级别锁定改用表级别的锁定,造成并发性能的降低
-当Query 使用的索引并不包含所有过滤条件的时候,数据检索使用到的索引键所只想的数据可能有部分并不属于该Query 的结果集的行列,但是也会被锁定,因为间隙锁锁定的是一个范围,而不是具体的索引键
- 当Query 在使用索引定位数据的时候,如果使用的索引键一样但访问的数据行不同的时候(索引只是过滤条件的一部分),一样会被锁定
- NDB Cluster
-锁定对象的颗粒度很小
- 锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能
- 由于锁定资源的颗粒度很小,所以每次获取锁释放锁要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁
- 表级锁定(table-level)
- MyISAM
- MyISAM 存储引擎使用的锁定机制完全是由MySQL 提供的表级锁定实现
-大颗粒度的锁定机制
-获取锁释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题
-负面影响就是出现锁定资源争用的概率也会最高,致使并发度大打折扣
- 页级锁定(page-level)
- 锁定颗粒度介于行级锁定表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间
-页级锁定和行级锁定一样,会发生死锁
- 优化策略
- 缩短锁定时间
-尽两减少大的复杂Query,将复杂Query分拆成几个小的Query 分布进行
-尽可能的建立足够高效的索引,让数据检索更迅速
-尽量让MyISAM存储引擎的表只存放必要的信息,控制字段类型
-利用合适的机会优化MyISAM 表数据文件
-分离能并行的操作,MyISAM 存储引擎有一个控制是否打开Concurrent Insert功能的参数选项:
-concurrent_insert=2无论MyISAM 存储引擎的表数据文件的中间部分是否存在因为删除数据而留下的空闲空间,都允许在数据文件尾部进行Concurrent Insert
-concurrent_insert=1,当MyISAM 存储引擎表数据文件中间不存在空闲空间的时候,可以从文件尾部进行Concurrent Insert
-concurrent_insert=0无论MyISAM 存储引擎的表数据文件的中间部分是否存在因为删除数据而留下的空闲空间,都不允许Concurrent Insert
-合理利用读写优先级
- Innodb行锁优化建议
-尽可能让所有的数据检索都通过索引来完成,从而避免Innodb 因为无法通过索引键加锁升级为表级锁定
-合理设计索引,让Innodb 在索引键上面加锁的时候尽可能准确,尽可能的缩小锁定范围,避免造成不必要的锁定而影响其他Query 的执行
-尽可能减少基于范围的数据检索过滤条件,避免因为间隙锁带来的负面影响而锁定了不该锁定的记录
-尽量控制事务的大小减少锁定的资源量锁定时间长度
-在业务环境允许的情况下,尽量使用较低级别的事务隔离,以减少MySQL 因为实现事务隔离级别所带来的附加成本
- MySQL数据库Query优化思路和原则
-优化更需要优化的Query
-什么Query的优化能给系统整体带来更大的收益,就更需要优化
-一般来说,高并发低消耗(相对)的Query 对整个系统的影响远比低并发高消耗的Query 大
-定位优化对象的性能瓶颈
-首先要判断出这个Query 的瓶颈到底是IO还是CPU。到底是因为在数据访问消耗了太多的时间,还是在数据的运算(如分组排序等)方面花费了太多资源?
-自带的PROFILING功能很清楚的找出一个Query的瓶颈所在
-明确的优化目标
- 需要了解数据库目前的整体状态,该Query 在整个应用系统中所实现的功能。就能知道数据库所能承受的最大压力,也就清楚了我们能够接受的最悲观情况
-把握了该Query 相关数据库对象的信息,我们就应该知道实现该Query 的消耗最理想情况下需要消耗多少资源,最糟糕又需要消耗多少资源
-从Explain 入手
-只有Explain 才能告诉你,这个Query 在数据库中是以一个什么样执行计划来实现的
-在优化任何一个SQL 语句之前,应该先有一个预定的执行计划,通过不断的调整尝试,借助Explain 来验证调整的结果是否满足自己预定的执行计
-永远用小结果集驱动大的结果集
-只取出自己需要的Columns
-仅仅使用最有效的过滤条件
-尽可能避免复杂的Join和子查询
-充分利用 Explain 和 Profiling
- Explain使用
-EXPLAIN 命令来告诉我们他将使用一个什么样的执行计划来优化我们的Query
- Profiling使用
-Query Profiler 是一个使用非常方便的Query 诊断分析工具
-通过该工具可以获取一条Query 在整个执行过程中多种资源的消耗情况,如CPU,IO,IPC,SWAP 等,以及发生的PAGE FAULTS,CONTEXT SWITCHE
-同时还能得到该Query 执行过程中MySQL 所调用的各个函数在源文件中的位置
-开启profiling 参数:set profiling=1
- 索引
- 利处
- 极大的提高检索效率加快检索降低检索过程中所需要读取的数据量
- 索引还有一个非常重要的用途,那就是降低数据的排序成本
- 在进行排序分组操作中利用好索引,将会极大的降低CPU 资源的消耗
-弊端
- 最明显的资源消耗就是增加了更新所带来的IO量调整索引所致的计算量
-如何判定是否需要创建索引
- 较频繁作为查询条件的字段应该创建索引
- 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件(如状态字段,类型字段等)
- 更新非常频繁的字段不适合创建索引
- 不会出现在WHERE子句中的字段不该创建索引
- Join优化
-尽可能减少Join语句中的Nested Loop的循环总次数
-优先优化Nested Loop 的内层循环
-保证Join语句中被驱动表上Join条件字段已经被索引
-无法保证被驱动表的Join条件字段被索引且内存资源充足的前提下,不要太吝惜JoinBuffer的设置
-Sort优化
-加大max_length_for_sort_data 参数的设置
-去掉不必要的返回字段
-增大sort_buffer_size 参数设置
-Group By优化
-尽可能让MySQL 可以利用索引来完成GROUP BY 操作
-无法使用索引完成GROUP BY 的时候,必须要有足够的sort_buffer_size 来供MySQL 排序的时候使用,而且尽量不要进行大结果集的GROUPBY 操作
- MySQL数据库Schema设计优化
- 适度冗余 - 让Query尽量减少Join
- 大字段垂直分拆 - Summary表优化
- 大表水平分拆 - 基于类型的分拆优化
- 统计表 - 准实时优化
- MySQL Server(服务器本身)性能优化
- MySQL常用存储引擎优化
4,MySQL可扩展设计的基本原则
- 事务相关性最小化原则
- 数据一致性原则
- 高可用及数据安全原则
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics