数据库性能优化(MySQL)

序:mysql

    即便有较长的缓存有效期和较理想的缓存命中率,可是缓存的建立和缓存过时后的重建都是须要访问数据库的。对数据库写操做不是很容易引入缓存策略。web

11.1 查看数据库状态sql

    能够经过show status、show innodb status 来查看MySQL数据库的状态,使用mysqlreport这个第三方工具可以使数据库状态报告更好看(mysqlreport本质是经过MySQL内部命令和工具来统计状态的)。数据库

11.2 正确使用索引缓存

    在影响数据库查询性能的众多因素中,索引绝对是一个重量级的因素,若是索引使用不当,则数据库的其它优化可能无济于事。数据结构

    索引是用于快速定位到表记录所在地址的一种数据结构(BTree、Hash、RTree等)。经过索引去查找记录即为索引扫描。多线程

    索引扫描不必定比全表扫描性能更好,要看状况。查询优化器会为一次查询是否使用索引以及决定使用哪一个索引,固然,有时查询优化器也会犯错误。并发

    数据库的索引须要定位到每行记录,全部索引项的数量也会很是多,经过索引列表查找某索引项也会存在必定的小开销。异步

    除了普通索引外还有惟一索引、主键索引、非空索引、全文索引等,不一样的索引只是约束和用途不同。像惟一索引在插入数据时就会增长必定的开销,由于它每插入一次都要判断是否重复。分布式

    通常若是一个字段出如今查询语句基于行的选择、分组和排序,那么为该字段创建索引多是有价值的。

    explain只可分析查询语句,不能用于分析更新操做的语句。

    在explain中,若type为const,说明查询能够经过索引直接找到匹配行,key为PRIMARY说明使用了主键索引。若type为all,说明使用了全表扫描,索引未使用上,此时的key 为空。若type为ref,说明查询的结果可能有多个匹配行。若type为index,说明查询只须要在索引中扫描便可。

    一次查询对一个数据表只能使用一个索引,不能进行索引效应叠加。

    最左前缀是使用组合索引的最基本原则。

    非顺序的索引类型如hash对order by是无效的。

    对于包含group by的查询,数据库通常是先将记录分组后放到临时表中,而后对其进行函数运算。这时如有恰当索引时,可以使用索引来代替临时表的使用。

    可使用慢查询配置来记录查询慢的语句,也能够记录未使用索引的查询语句。

    为了节省查找索引的时间,能够将索引缓存起来放到内存中,这样最理想的状况,索引能够直接在内存中查找而不须要访问磁盘。MyISAM表包括3个文件,分别是.frm、.MYI、.MYD。也即MyISAM表类型只缓存索引不缓存数据文件。因为存在索引写缓存机制,MyISAM表类型对于索引的写操做存在延迟。

    在使用索引时也要考虑到其代价,索引会占据更多的磁盘空间,有时甚至比数据文件还要大。当在创建了索引的字段上进行更新时,其索引也须要更新,这个开销可不小。索引也须要花时间来维护。

11.3 锁定与等待

    锁机制是影响查询性能的另外一个因素,当多个并发用户同时访问同一资源时,数据库为保证并发访问的一致性,使用数据库锁来协调访问。

    查询时间的开销包括查询自己的计算时间和查询前的等待时间,索引影响的是前者,锁机制影响的是后者。

    MySQL为MyISAM表类型提供的是表锁。表锁容许多个线程同时读取数据(select),但对于更新操做会排斥全部其它的查询包括select,并且更新操做具备默认的高优先级。

    若是大部分为查询操做,只有少量更新操做,则不会存在太多的锁等待。

    MySQL为InnoDB表类型提供的是行锁。行锁能够带来update和select不一样线程对不一样的行记录能够并发地进行。

    行锁并不必定比表锁快,开销不必定比表锁小,尤为是涉及全表扫描时行锁的开销更大。

11.4 事务性表的性能

    InnoDB除了支持行锁外,它还支持事务,InnoDB实现事务的方法是经过预写日志的方式。当有事务提交时,InnoDB将它写入到内存的事务日志缓冲区中,随后将事务日志写入磁盘,从而更新实际的数据和索引。

    事务日志写入磁盘的时机:

    innodb_flush_log_at_trx_commit=1时,表明事务提交时事务日志当即写入磁盘,同时更新数据和索引。

    innodb_flush_log_at_trx_commit=0时,表明事务提交时事务日志不当即写入磁盘,而是每隔1秒写入磁盘文件一次,并刷新到磁盘同时更新数据和索引。

    innodb_flush_log_at_trx_commit=2时,表明事务提交时事务日志当即写入磁盘文件,每隔1秒刷新到磁盘同时更新数据和索引。

    经过以上3种时机能够对比出它们的可靠性和性能。

11.5 使用查询缓存

    查询缓存就是将select查询结果放在内存中,key是select语句,value是该查询语句的结果。不管是MyISAM仍是InnoDB引擎,查询缓存均可以很好地工做,起到提高性能的做用。查询缓存要注意缓存过时策略,在MySQL中,若一个表中有更新操做,则该表的全部查询缓存将失效。所以,对于select密集型更新不多的应用很适合使用查询缓存。

11.6 临时表

    在explain查询语句时,有时能够看到Using temporary状态,这说明查询过程使用了临时表来存储中间数据,能够经过合理使用索引来避免建立临时表状况。若临时表的使用不可避免,那么也应该尽可能减小临时表自己的开销。

    MySQL的临时表能够建立在磁盘、内存和临时文件中。固然,建立在磁盘上的开销最大。有时在使用show processlist能够看到查询状态中有Coping to tmp table on disk,这说明MySQL在将临时表从内存中复制到磁盘上以节省内存空间。

    能够经过tmp_table_size选项来设置用于存储临时表的内存空间大小。一旦空间不够用才会使用磁盘来存储。

11.7 线程池

    MySQL使用多线程来处理并发链接。为减小重复线程的建立能够尽可能使用持久链接或将链接缓存起来(经过在my.cnf中配置thread_table_size=个数来设置)。

11.8 反范式设计

    所谓范式就是对关系数据库中的关系的要求或约束,有不一样程序的要求就有不一样的范式。一般遵循到3NF便可,3NF就是非主键字段之间不能存在依赖关系,这样能够避免删除、更新、插入异常,保持关系的一致性,减小数据冗余。

    反范式化就是违背关系设计的要求或约束,用于减小读取数据的开销,增长必定的数据冗余,但这样同时也增长了写数据的开销,由于要保持冗余数据的一致性。固然,为了保证数据库写性能能够异步写数据。若不想反范式则可使用非关系型数据库。

11.9 使用非关系数据库

    key-value数据库使用半结构化存储数据,全部数据只有一个索引即key,能够将反范式化引起的数据副本保存到key-value数据库中,这样比关系数据库具备更出色的并发性能。

    MemcacheDB在性能方面比较出色,是一个分布式的key-value数据库,使用Memcache协议,这意味着使用了Memcache的web应用能够不进行任何的修改而迁移到MemcacheDB上。

    不是全部的应用都适合用key-value数据库,该用关系查询的时候仍是得用关系数据库,key-value数据库只是为避免反范式化引起的写数据开销方案之一。固然,MemcacheDB封装了Berkeley DB的复制功能,能够经过主从复制来扩展MemcacheDB的规模,提高可用性。

相关文章
相关标签/搜索