Mysql优化

Posted 一只可爱的小狐狸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql优化相关的知识,希望对你有一定的参考价值。

mysql优化

优化SQL的原则:

(1)减少数据访问: 设置合理的字段类型,启用压缩,通过索引访问等减少磁盘IO
(2返回更少的数据: 只返回需要的字段和数据分页处理 减少磁盘io及网络io
(3)减少交互次数: 批量DML操作,函数存储等减少数据连接次数
(4)减少服务器CPU开销: 尽量减少数据库排序操作以及全表查询,减少cpu 内存占用
(5)利用更多资源: 使用表分区,可以增加并行操作,更大限度利用cpu资源

SQL优化的方向:

优化MySQL主要从两个方向:硬件级别(Hardware Level)、数据库级别(Database Level)

1.硬件级别

(1)磁盘寻找(Disk seeks):磁盘需要一段时间才能找到一段数据。对于现代磁盘来说,这种平均时间通常低于10ms,因此理论每秒100次寻找。这一次用新的磁盘缓慢地改进,并且对于单个表是很难优化的。优化查找时间的方法是将数据分发到一个以上的磁盘上。

(2)磁盘读写(Disk reading and writing)。当磁盘处于正确位置时,我们需要读取或写入数据。使用现代磁盘,一个磁盘可以提供至少10到20Mb/s的吞吐量。这比磁盘寻找更容易优化,因为您可以从多个磁盘并行读取。

(3)CPU(CPU cycles)。当数据在主存储器中时,我们必须处理它以得到结果。与内存量相比,具有大数据库量的表是最常见的限制因素。但是对于小表来说,速度通常不是问题。

(4)存储带宽(Memory bandwidth)。当CPU需要比CPU缓存中更多的数据时,主存储器带宽成为瓶颈。对于大多数系统来说,这是一个不常见的瓶颈,但也是一个需要注意的点

2.数据库级别

(1) 表结构是否正确(Are the tables structured properly?):特别的是列是否具有正确的类型,和表中列的个数是否正确。例如:对于执行频繁更新的应用通常设计更多表,每个表的列并不多。而对于需要进行大量分析的应用通常设计更少的表,而每个表的列更多一些。

(2)正确的设置索引达到查询高效(Are the right indexes in place to make queries efficient?):需要考虑的是什么SQL会导致索引无效,什么情况会让查询效率更高

(3)对于不同情况选择不同的存储引擎(Are you using the appropriate storage engine for each table, and taking advantage of the strengths and features of each storage engine you use? )选择不同的存储引擎对性能和可伸缩性具有较大的影响

(4)每张表是否具有适当的行格式(Does each table use an appropriate row format?):主要取决于适当的存储引擎。压缩表可以占用更低的磁盘空间和更少的I/O操作。压缩表适用于InnoDB和MyISM存储引擎。

(5)应用程序是否使用适当的锁策略(Does the application use an appropriate locking strategy? ):在具有高并发、分布式应用程序中,选择适当的锁策略以保证数据的共享性和特定的情况下独占数据。InnoDB存储引擎在不需要我们参与下能处理大部分锁问题,允许数据库实现更好的并发性,减少代码调优量。

(6)所有缓存区域使用的大小是否都正确(Are all memory areas used for caching sized correctly?):配置的原则是缓存区域大到足以容纳所有频繁访问的数据,但又不能太大,否则导致过量占用物理内存而导致分页。一般情况下需要配置InnoDB的缓冲池、MyISAM密钥缓存和MySQL的查询缓存

优化可能带来的问题

1.优化不总是对一个单纯的环境进行,还很可能是一个复杂的已投产的系统。

2 .优化手段本来就有很大的风险,只不过你没能力意识到和预见到!

3 .任何的技术可以解决一个问题,但必然存在带来一个问题的风险!

4 .对于优化来说解决问题而带来的问题,控制在可接受的范围内才是有成果。

结论:保持现状或出现更差的情况都是失败!

优化的需求

1 稳定性和业务可持续性,通常比性能更重要!

2 优化不可避免涉及到变更,变更就有风险!

3 优化使性能变好,维持和变差是等概率事件!

结论:所以优化工作,是由业务需要驱使的!!!

Mysql底层执行原理

SQL执行流程
  1. 客户端向服务器端发送SQL命令

  2. 服务器端连接模块连接并验证

  3. 缓存模块解析SQL为Hash并与缓存中Hash表对应。如果有结果直接返回结果,如果没有对应继续向下执行

  4. 解析器解析SQL为解析树,如果出现错误,报SQL解析错误。如果正确,向下传递

  5. 预处理器对解析树继续处理,处理成新的解析树。

  6. 优化器根据开销自动选择最优执行计划,生成执行计划

  7. 执行器执行执行计划,访问存储引擎接口

  8. 存储引擎访问物理文件并返回结果

  9. 如果开启缓存,缓存管理器把结果放入到查询缓存中。

  10. 返回结果给客户端

在mysql8.0以下提供了缓存的功能,8.0以上的版本就取消的缓存的这个功能

原因:MySQL之前有一个查询缓存Query Cache,从8.0开始,不再使用这个查询缓存!!!

MySQL查询缓存是查询结果缓存。它将以SEL开头的查询与哈希表进行比较,如果匹配,则返回上一次查询的结果。进行匹配时,查询必须逐字节匹配,例如 SELECT * FROM t1; 不等于select * from t1;,此外,一些不确定的查询结果无法被缓存,任何对表的修改都会导致这些表的所有缓存无效。因此,适用于查询缓存的最理想的方案是只读,特别是需要检查数百万行后仅返回数行的复杂查询。如果你的查询符合这样一个特点,开启查询缓存会提升你的查询性能。

随着技术的进步,经过时间的考验,MySQL的工程团队发现启用缓存的好处并不多。

首先,查询缓存的效果取决于缓存的命中率,只有命中缓存的查询效果才能有改善,因此无法预测其性能。

其次,查询缓存的另一个大问题是它受到单个互斥锁的保护。在具有多个内核的服务器上,大量查询会导致大量的互斥锁争用。

通过基准测试发现,大多数工作负载最好禁用查询缓存(5.6的默认设置):query_cache_type = 0

存储引擎

mysql提供的几种引擎:

  1. MyISAM
  2. InnoDB
  3. Memory
  4. ARCHIVE
  5. BLACKHOLE
  6. PERFORMANCE_SCHEMA
  7. MRG_MYISAM
  8. CSV
  9. | FEDERATED
常用的两种引擎:InnoDB和MyISAM

(1)MyISAM:

MyISAM是MySQL的ISAM扩展格式(MySQL5.5之前版本的缺省数据库引擎)数据库引擎。除了提供ISAM里所没有的索引和字段管理的大量功能,MyISAM还使用一种表格锁定的机制,来优化多个并发的读写操作,其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。MyISAM还有一些有用的扩展,例如用来修复数据库文件的MyISAMCHK工具和用来恢复浪费空间的 MyISAMPACK工具。MYISAM强调了快速读取操作,这可能就是为什么MySQL受到了WEB开发如此青睐的主要原因:在WEB开发中你所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和INTERNET平台提供商只允许使用MYISAM格式。MyISAM格式的一个重要缺陷就是不能在表损坏后恢复数据。

MyISAM引擎使用注意:必须经常使用Optimize Table命令清理空间;必须经常备份所有实时数据。工具有用来修复数据库文件的MyISAMCHK工具和用来恢复浪费空间的 MyISAMPACK工具。不支持事务。数据越多,写操作效率越低。因为要维护数据和索引信息。(索引列越多,相对效率越低。)

(1.1)如果使用该数据库引擎,会生成三个文件:

.frm:表结构信息

.MYD:数据文件

.MYI:表的索引信息

(2)InnoDB

InnoDB数据库引擎都是造就MySQL灵活性的技术的直接产品,这项技术就是MYSQL++ API。在使用MySQL的时候,你所面对的每一个挑战几乎都源于ISAM和MyISAM数据库引擎不支持事务处理(transaction process)也不支持外键。尽管要比ISAM和MyISAM引擎慢很多,但是InnoDB包括了对事务处理和外键的支持,这两点都是前两个引擎所没有的。是现在的MySQL(5.5以上版本)常用版本默认引擎,也是默认的存储引擎。

MySQL 官方对InnoDB是这样解释的:InnoDB给MySQL提供了具有提交、回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读,这些特色增加了多用户部署的性能。没有在InnoDB中扩大锁定的需要,因为在InnoDB中行级锁定适合非常小的空间。InnoDB也支持FOREIGN KEY强制。在SQL查询中,你可以自由地将InnoDB类型的表与其它MySQL的表的类型混合起来,甚至在同一个查询中也可以混合。

InnoDB是为处理巨大数据量时的最大性能设计,它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的

(2.1)InnoDB特点:

1)支持事务

2)数据多版本读取(InnoDB+MyISAM+ISAM)

3)、锁定机制的改进

4)、实现外键

InnoDB和MyISAM的区别

  1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin transaction和commit之间,组成一个事务;

  2. InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MyISAM会失败;

  3. InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

  4. InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

SQL调优思路

1、查看slow-log,分析slow-log,分析出查询慢的语句。

2、按照一定优先级,进行一个一个的排查所有慢语句。

3、分析top sql,进行explain调试,查看语句执行时间。

4、调整索引或语句本身。

以上是关于Mysql优化的主要内容,如果未能解决你的问题,请参考以下文章

mysql优化专题」90%程序员都会忽略的增删改优化

基于查询计划优化 MySQL 查询的建议

我必须得告诉你的MySQL优化原理3

谈谈如何优化MYSQL数据库查询

mysql优化要点

MySQL数据库优化法则总结