Mysql性能调优
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql性能调优相关的知识,希望对你有一定的参考价值。
1. 宏观上调优可以考虑三个部分,分别为硬件、网络、软件,此处主要考虑软件调优
(1)软件调优包括:表设计(范式、字段类型、数据存储引擎)、SQL语句语索引、配置文件参数、文件系统、操作系统、mysql版本、体系架构
2. 表设计
(1) 第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本数据类型构成,包括整型、字符型、逻辑型、日期型等。(只要是关系型数据库都符合第一范式)
(2) 第二范式(2NF):要求实体的属性完全依赖于主关键字,即只能有一个主关键字。也即非关键字段都依赖于主键
(3) 第三范式(3NF):不存在非关键字段对任一候选关键字段的传递函数依赖。
3. 字段类型的选择:一般原则是保小不保大,能用占字节少的字段就不用大字段。
3.1 数值类型
(1)录入手机号码用bigint
(2)IP地址可以采用unsigned int整型,并采用INET_NTOA()负责将数字转换为IP地址,INET_ATON()负责将IP地址转换为数字
(3)根据需要选择最小整数类型
3.2 字符类型
(1)计算varchar的最大长度:varchar(32766)
3.3 时间类型
4. 采用更合适的锁机制
4.1 MYSQL的锁分为三种:
(1)表级锁:开销小、加锁快,不会出现死锁;锁粒度大,发生冲突的概率最高,并发度最低。MyISAM引擎
(2)行级锁:开销大、加锁慢、会出现死锁;锁粒度最小,发生冲突的概率最低,并发度最高。InnoDB引擎
(3)页面锁:介于中间。NDB引擎
4.2 MyISAM引擎:
(1)对MyiSAM表的读操作(加读锁),其它进程可以读,但是会阻塞同一表的写操作;
(2)对MyISAM表的写操作,会阻塞其它线程对同一表的读写操作,只有当写锁释放后,才会执行其它进程的读写操作;
4.3 InnoDB引擎:InnoDB存储引擎是通过给索引上的索引项加锁来实现的,这说明只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将采用表锁 (为防止在高并发访问下,大量事务因无法立即获得所需的锁而挂起,会占用大量计算机资源,造成严重的性能问题,这时可以通过设置合适的锁等待超时阈值参数innode_lock_wait_timeout来解决,一般设置为100s)
5 选择合适的事务隔离级别
5.1 事务的属性:
(1)原子性
(2)一致性
(3)隔离性
(4)持久性
5.2 不确定的读取情况
(1)脏读:一个事务开始读取某行数据,另外一个事务已经更新了此数据但没有及时提交。而另一事务可能发生回滚。
(2)不可重复读:一个事务对同一行数据重复读取两次,但是得到了不同的结果。例如,在两次读取的途中,有另外一个事务对该行的数据进行了修改并提交。
(3)两次更新问题:无法重复读取的特例。两个并发事务同时读取同一行数据,然后其中一个对它进行修改提交,而另一个也进行了修改提交。这就造成第一次写操作失效
(4)幻读:事务在操作过程中进行了两次查询,第二次查询的结果包含了第一次查询中未出现的数据。这是因为在两次查询过程中有另外一个事务插入数据。
5.3 InnodDB 事务隔离级别
(1)Read Uncommitted 读未提交:会产生脏读取。(“排他写锁”)
(2)Read Committed 读提交:会产生不可重复读取。(“瞬间共享读锁”和“排他写锁”)
(3)Repeated Read 可重复读取:会产生幻读。(“共享读锁”和“排他写锁”)
(4)Serilizable 序列化:提供严格的事务隔离,事务严格序列化,事务只能一个接一个地执行,不能并发执行。
6. SQL优化与合理利用索引
6.1 通过开启慢日志来定位执行很慢的SQL语句:(explain优化器查询)
开启慢日志的方法:在my.cnf配置文件中,加入以下参数:
slow_query_log=1
slow_query_log_file=mysql.slow
long_query_time=2(超过2秒的SQL会记录下来)
6.2 SQL优化案例分析
(1)not in 子查询优化:尽量避免子查询,采用left join表连接
(2)模式匹配like ‘%xxx%‘: 在MYSQL中,like ‘xxx%’ 可以用到索引,而like ‘%xxx%‘则不行;利用覆盖索引来进行优化
(3)limit分页优化
(4)count(*)统计数据如何加快速度:利用辅助索引count(辅助索引)快于count(*);
(5)SQL语句中有or条件,则会用不到索引;将其改为union all结果集合并
(6)不必要的排序;
(7)不必要的嵌套select查询
(8)不必要的表自身连接、
(9)用where子句代替having子句
6.3 合理使用索引:索引有一定开销,例如写入和更新或删除操作时都需要更新索引。此外,只有当某列被用于where子句时,才能享受到索引性能提升的好处
(1)单列索引和联合索引的对比:联合索引遵循最左侧原则
(2)字段使用函数,将不能用到索引
(3)致命的无引号导致全表扫描,无法用到索引:
(4)当取出的数据量超过表中数据的20%时,优化器就不会使用索引,而是全表扫描
(5)考虑不为某些列建立索引:
(6)group by、order by优化
(7)MYSQL5.6 InnoDB引擎支持全文索引
(8)MYSQL5.6支持explain update/select
(9)MySQL5.6优化了index merge合并索引,即可以实现一条SQL可以使用两个索引了
7. my.cnf配置文件调优
7.1 per_thread_buffers优化:为每个连接到MySQL的用户进程分配内存
(1)read_buffer_size: 用于表的顺序扫描,表示每个线程分配的缓冲区大小。
(2)read_rnd_buffer_size: 用于表的随机读取,表示每个线程分配的缓冲区大小
(3)sort_buffer_size: 在表进行order by 和group by 排序操作时,由于排序的字段没有索引,会出现Using filesort,为了提高性能,可用此参数增加每个线程分配的缓冲区大小。
(4)thread_stack: 表示每个线程的堆栈大小
(5)join_buffer_size:
(6)max_connections: 该参数用来设置最大连接数,默认100。一般设置为512到1000即可。
7.2 global_buffers优化:用于在内存中缓存从数据文件中检索出来的数据块,可以大大提高查询和更新数据的性能。
(1)innodb_buffer_pool_size: 核心参数,默认为128MB
(2)innodb_additional_mem_pool_size:用来存储数据字典信息和其他内部数据结构,表越多,需要分配的内存越多,一版设置为16MB
(3)innodb_log_buffer_size: 事务日志所使用的缓冲区。
7.3 Query Cache在不同环境下的使用: 其功能是缓存select语句和结果集。查询缓存绝不会返回过期数据,当数据被修改后,在查询缓存中的任何相关词条都会被清除。
如果环境中写操作很多,不适合打开query_cache_type,如果读操作频繁而写操作很少,则打开query_cache_type=1。
以上是关于Mysql性能调优的主要内容,如果未能解决你的问题,请参考以下文章