MySQL性能调优总结

MyISAM表锁优化建议

用表级锁定在锁定实现的过程中比实现行级锁定或者页级锁所带来的
附加成本都要小,锁定本身所消耗的资源也是最少。但是由于锁定的颗粒度比较到,所以造成锁定资源
的争用情况也会比其他的锁定级别都要多,从而在较大程度上会降低并发处理能力。
1、 缩短锁定时间
唯一的办法就是让我们的Query执行时间尽可能的短。
a) 尽两减少大的复杂Query,将复杂Query分拆成几个小的Query分布进行;
b) 尽可能的建立足够高效的索引,让数据检索更迅速;
c) 尽量让MyISAM存储引擎的表只存放必要的信息,控制字段类型;
d) 利用合适的机会优化MyISAM表数据文件;
2、 分离能并行的操作
说到MyISAM的表锁,而且是读写互相阻塞的表锁,可能有些人会认为在MyISAM存储引擎的表上就只
能是完全的串行化,没办法再并行了。大家不要忘记了, MyISAM的存储引擎还有一个非常有用的特性,
那就是Concurrent Insert(并发插入)的特性。
MyISAM存储引擎有一个控制是否打开Concurrent Insert功能的参数选项: concurrent_insert, 可
以设置为0, 1 或者2。三个值的具体说明如下:
a) concurrent_insert=2,无论 MyISAM 存储引擎的表数据文件的中间部分是否存在因为删除数据
而留下的空闲空间,都允许在数据文件尾部进行Concurrent Insert;
b) concurrent_insert=1,当 MyISAM存储引擎表数据文件中间不存在空闲空间的时候,可以从文
件尾部进行Concurrent Insert;
c) concurrent_insert=0,无论 MyISAM 存储引擎的表数据文件的中间部分是否存在因为删除数据
而留下的空闲空间,都不允许Concurrent Insert。
3、合理利用读写优先级
在本章各种锁定分析一节中我们了解到了 MySQL的表级锁定对于读和写是有不同优先级设定的,默
认情况下是写优先级要大于读优先级。所以,如果我们可以根据各自系统环境的差异决定读与写的优先
级。如果我们的系统是一个以读为主,而且要优先保证查询性能的话,我们可以通过设置系统参数选项
low_priority_updates=1,将写的优先级设置为比读的优先级低,即可让告诉 MySQL 尽量先处理读请
求。当然,如果我们的系统需要有限保证数据写入的性能的话,则可以不用设置 low_priority_updates
参数了

Innodb行锁优化建议

Innodb存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁
定会要更高一些,但是在整体并发处理能力方面要远远优于MyISAM的表级锁定的。当系统并发量较高的
时候, Innodb的整体性能和MyISAM相比就会有比较明显的优势了。但是, Innodb的行级锁定同样也有其脆弱的一面,当我们使用不当的时候,可能会让Innodb的整体性能表现不仅不能比MyISAM高,甚至可能会更差。

要想合理利用Innodb的行级锁定,做到扬长避短,我们必须做好以下工作:
a) 尽可能让所有的数据检索都通过索引来完成,从而避免Innodb因为无法通过索引键加锁而升级
为表级锁

b) 合理设计索引,让Innodb在索引键上面加锁的时候尽可能准确,尽可能的缩小锁定范围,避免
造成不必要的锁定而影响其他Query的执行;
c) 尽可能减少基于范围的数据检索过滤条件,避免因为间隙锁带来的负面影响而锁定了不该锁定
的记录;
d) 尽量控制事务的大小,减少锁定的资源量和锁定时间长度;
e) 在业务环境允许的情况下,尽量使用较低级别的事务隔离,以减少 MySQL因为实现事务隔离级
别所带来的附加成本;
由于Innodb的行级锁定和事务性,所以肯定会产生死锁,下面是一些比较常用的减少死锁产生概率
的的小建议,读者朋友可以根据各自的业务特点针对性的尝试:
a) 类似业务模块中,尽可能按照相同的访问顺序来访问,防止产生死锁;
b) 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
c) 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁
产生的概率

Query优化思路

Query 语句的优化思路和原则
1. 优化更需要优化的Query;
2. 定位优化对象的性能瓶颈;
3. 明确的优化目标;
4. 从 Explain 入手;
5. 多使用profile
6. 永远用小结果集驱动大的结果集;
7. 尽可能在索引中完成排序;
8. 只取出自己需要的Columns;
9. 仅仅使用最有效的过滤条件;
10. 尽可能避免复杂的Join和子查询


索引的利处:

提高数据检索的效率,降低数据库的IO成本,加快检索时间,降低检索过程中所需要读取的数据量。

降低数据的排序成本,排序字段刚好与索引字段一致。


索引的弊端:

索引的创建,索引的更新,会带来资源消耗问题。

索引建立条件:


◆ 较频繁的作为查询条件的字段应该创建索引;
◆ 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件;
◆ 更新非常频繁的字段不适合创建索引;
◆ 不会出现在 WHERE 子句中的字段不该创建索引;

适合索引的建议:

1. 对于单键索引,尽量选择针对当前 Query 过滤性更好的索引;
2. 在选择组合索引的时候,当前 Query 中过滤性最好的字段在索引字段顺序中排列越靠前越好;
3. 在选择组合索引的时候,尽量选择可以能够包含当前 Query 的 WHERE 子句中更多字段的索
引;
4. 尽可能通过分析统计信息和调整 Query 的写法来达到选择合适索引的目的而减少通过使用
Hint 人为控制索引的选择,因为这会使后期的维护成本增加,同时增加维护所带来的潜在风险


MySQL 中索引使用相关的限制


1. MyISAM存储引擎索引键长度总和不能超过1000字节;
2. BLOB和TEXT类型的列只能创建前缀索引;
3. MySQL 目前不支持函数索引;
4. 使用不等于( != 或者 <>)的时候 MySQL 无法使用索引;
5. 过滤字段使用了函数运算后(如abs(column)), MySQL无法使用索引;
6. Join 语句中 Join 条件字段类型不一致的时候 MySQL 无法使用索引;
7. 使用 LIKE 操作的时候如果条件以通配符开始('%abc...') MySQL 无法使用索引;
8. 使用非等值查询的时候 MySQL 无法使用 Hash 索引;
9.在我们使用索引的时候,需要注意上面的这些限制,尤其是要注意无法使用索引的情况,因为这很
容易让我们因为疏忽而造成极大的性能隐


Join 的实现原理及优化思路


Join 语句的优化


1. 尽可能减少 Join 语句中的 Nested Loop 的循环总次数;如何减少 Nested Loop 的循环总次数?最有效的办法只有一个,那就是让驱动表的结果集尽可能的小。用小的结果集驱动大的结果集。

2. 优先优化Nested Loop 的内层循环;
不仅仅是在数据库的 Join 中应该做的,实际上在我们优化程序语言的时候也有类似的优化原则。内层循环是循环中执行次数最多的,每次循环节约很小的资源,在整个循环中就能节约很大的资源。
3. 保证 Join 语句中被驱动表上 Join 条件字段已经被索引;
4. 当无法保证被驱动表的 Join 条件字段被索引且内存资源充足的前提下,不要太吝惜 JoinBuffer 的设置
 

order by 优化

MySQL 目前可以通过两种算法来实现数据的排序操作。
1. 取出满足过滤条件的用于排序条件的字段以及可以直接定位到行数据的行指针信息,在 Sort Buffer 中进行实际的排序操作,然后利用排好序之后的数据根据行指针信息返回表中取得客户端请求的其他字段的数据,再返回给客户端;
2. 根据过滤条件一次取出排序字段以及客户端请求的所有其他字段的数据,并将不需要排序的字段存放在一块内存区域中,然后在 Sort Buffer 中将排序字段和行指针信息进行排序,最后再利用排序后的行指针与存放在内存区域中和其他字段一起的行指针信息进行匹配合并结果集,再按照顺序返回给客户端;

Group by优化

两种优化思路:
1. 尽可能让 MySQL 可以利用索引来完成 GROUP BY 操作,当然最好是松散索引扫描的方式最佳。
在系统允许的情况下,我们可以通过调整索引或者调整 Query 这两种方式来达到目的;
2. 当无法使用索引完成 GROUP BY 的时候,由于要使用到临时表且需要 filesort,所以我们必须
要有足够的 sort_buffer_size 来供 MySQL 排序的时候使用,而且尽量不要进行大结果集的 GROUP
BY 操作,因为如果超出系统设置的临时表大小的时候会出现将临时表数据 copy 到磁盘上面再进行
操作,这时候的排序分组操作性能将是成数量级的下降
 

Scheme设计性能优化

1.适度冗余--让Query减少join次数

2.大字段垂直拆分

将该大字段从原表中拆分出来,通过单独的表进行存放,让我们在访问其他数据的时候大大降低IO访问,从而使性能得到较大的改善。这种分拆之后的两个表的关系都是完全确定的一一对应关系,使用Join在性能方面的影响也并不是特别的大。
3.大表水平分拆 - 基于类型的分拆优化


化数据类型提高性能的主要原理在于以下几个方面:
1. 通过选用更“ 小” 的数据类型减少存储空间,使查询相同数据需要的IO资源降低;
2. 通过合适的数据类型加速数据的比较;

MySQL Server优化


网络连接与连接线程
● max_conecctions:整个MySQL允许的最大连接数;
● max_user_connections:每个用户允许的最大连接数
 

猜你喜欢

转载自my.oschina.net/u/1765168/blog/1790798