该栏目讲叙 MySQL 相关的知识体系,包括数据库简介、SQL 简介、数据定义、数据操作、数据查询及数据优化等模块
文章目录
应用优化
1、使用连接池
- :建立连接的代价是比较耗费资源的,所以有必要建立数据库连接池(
c3p0
、druid
),以提高访问的性能
2、避免重复索引
- :减少对数据库无用的重复请求,能一次连接获取全部结果的,就不用分次获取
3、应用层增加缓存
- :在应用中增加缓存层来达到减轻数据库负担。可以使用redis,也可以使用框架(MyBatis)提供的缓存机制
4、分布式数据库架构
- :分布式数据库架构适合大数据量、负载高的情况,它有良好的拓展性和高可用性。通过在多台服务器之间分布数据,可以实现在多台服务器之间的负载均衡,提高访问效率
5、主从复制
-
概述
:通过 MySQL 的主从复制,实现读写分离,使得增删改操作走主节点,查询操作走从节点,从而可以降低单台服务器的读写压力 -
原理
:复制是指将主数据库的二进制日志传到从库服务器中,然后在从库上对这些日志重新执行,从而使得从库和主库的数据保持同步。MySQL支持一台主库同时向多台从库进行复制, 从库同时也可以作为其他从服务器的主库,实现链状复制
-
好处
- 当主库出现问题,可以快速切换到从库提供服务
- 在从库上执行查询操作,从主库中更新,实现读写分离,降低主库的访问压力
- 在从库中执行备份,以避免备份期间影响主库的服务
-
搭建
主库配置
# 在master 的配置文件(/usr/my.cnf)中,配置如下内容
# mysql 服务ID,保证整个集群环境中唯一
server-id=1
# mysql binlog 日志的存储路径和文件名
log-bin=/var/lib/mysql/mysqlbin
# 错误日志,默认已经开启
# log-err
# mysql的安装目录
# basedir
# mysql的临时目录
# tmpdir
# mysql的数据存放目录
# datadir
# 是否只读,1 代表只读, 0 代表读写
read-only=0
# 忽略的数据, 指不需要同步的数据库
binlog-ignore-db=mysql
# 指定同步的数据库
# binlog-do-db=db01
# 重启
service mysql restart;
# 创建同步数据的账户,并且进行授权操作
grant replication slave on *.* to 'itcast'@'192.168.192.131' identified by 'itcast';
flush privileges;
# 查看master状态
show master status;
# 字段含义
File : 从哪个日志文件开始推送日志文件
Position : 从哪个位置开始推送日志
Binlog_Ignore_DB : 指定不需要同步的数据库
从库配置
# 在 slave 端配置文件中,配置如下内容
# mysql 服务端ID,唯一
server-id=2
# 指定binlog日志
log-bin=/var/lib/mysql/mysqlb
# 重启
service mysql restart;
# 执行如下指令:
change master to master_host= '192.168.192.130', master_user='itcast',
master_password='itcast', master_log_file='mysqlbin.000001', master_log_pos=413;
# 开启同步操作
start slave;
show slave status;
# 停止同步操作
stop slave;
SQL 缓存优化
1、简介
概述
:当执行完全相同的SQL语句的时候,服务器会直接从缓存中读取上一次查询的结果,当数据被修改了,之前缓存的数据会失效,对于修改比较频繁的表不适合开启查询缓存执行流程
2、操作
# 查看当前的MySQL数据库是否支持查询缓存
SHOW VARIABLES LIKE 'have_query_cache';
# 查看当前MySQL是否开启了查询缓存:0关闭、1打开、2只缓存查询
SHOW VARIABLES LIKE 'query_cache_type';
# 查看查询缓存的占用大小
SHOW VARIABLES LIKE 'query_cache_size';
# 查看查询缓存的状态变量
SHOW STATUS LIKE 'Qcache%';
# 启动缓存,在/usr/my.cnf配置中,增加以下配置,配置完毕之后,重启服务既可生效
query_cache_type = 1
# 定制select语句
SELECT SQL_CACHE id,name FROM customer; # 缓存查询结果的id,name
SELECT SQL_NO_CACHE id,name FROM customer; # 不缓存查询结果的id,name
3、缓存失效
- SQL 语句不一致时
- 查询语句中 有不确定的值时,如 now()、current_date()
- 查询语句中 不是查询表中的数据,如 select ‘A’
- 查询 系统数据库的表
- 在 存储的函数、触发器或事件的主体内执行的查询
- 当表被修改时,则使用该表的所有高速缓存数据将被缓存中删除
内存优化
1、优化原则
- 在操作系统和其他程序有足够的内存的情况下,则尽量将更多的内存分配给 MySQL 做缓存
- 排序区、连接区等缓存是分配给每个数据库会话专用的,其默认值的设置要根据最大连接数合理分配
- MyISAM 的数据文件读取依赖于操作系统自身的 IO 缓存,因此,如果有 MyISAM 表,就要预留更多的内存给操作系统做 IO 缓存
2、InnoDB 优化
概述
:InnoDB 使用一块内存区做 IO 缓存池,该缓存池用来缓存索引块、数据块相关参数
# 设置数据块和索引块的缓存区大小
innodb_buffer_pool_size:[size]
# 设置 InnoDB 日志缓存的大小
innodb_log_buffer_size:[size]
3、MyISAM 优化
概述
:MyISAM使用key_buffer缓存索引块,加速索引的读写速度。对于表的数据块,MyISAM没有特别的缓存机制,完全依赖于操作系统的IO缓存相关参数
# 设置索引块缓存区大小
key_buffer_size:[size]
# 设置读取缓存区的大小
read_buffer_size:[size]
# 设置排序缓存区的大小
read_rnd_buffer_size:[size]
并发优化
概述
:MySQL 数据库是多线程程序,可以通过设置并发相关的参数,有效利用资源,提高数据库的并发性能相关参数
# 设置最大连接数,默认值是151
max_connections:[size]
# 查询连接数
show variables like 'max_connections'
# 设置 MySQL 监听TCP端口时请求栈大小,默认值为50,当连接到达上限,则新来请求将会被缓存在堆栈中
back_log:[size]
# 设置 SQL 语句执行线程可打开表缓存的大小
table_open_cache:[size]
# 设置线程缓存大小,用于加快连接数据库的速度
thread_cache_size:[size]
# 设置InnoDB事务等待行锁时间,默认50ms,对于需要快速反馈的业务系统,可以将行锁的等待时间调小,
# 以避免事务长时间挂起;对于后台运行的批量处理程序来说,可以将行锁的等待时间调大,以避免发生大的回滚操作
innodb_lock_wait_timeout:[time]
锁机制
1、概述
- :InnoDB 对于对于 update、insert 和 delete 语句,会自动给涉及数据集加排他锁;但对于 select 语句,InnoDB 不会加任何锁
2、行锁模型
共享锁(S)
:又称为读锁,简称S锁,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改排它锁(X)
:又称为写锁,简称 X 锁,排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排它锁,但是获取排他锁的事务是可以对数据就行读取和修改
# 为select添加共享锁
select * from table_name where ... lock in share mode
# 为select添加排它锁
select * from table_name where ... for update
3、行锁升级为表锁
- :如果不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样
4、间隙锁的危害
- :使用条件的范围去查询数据,当该查询有共享或排它锁时,InnoDB 会给符合条件的已有数据进行加锁,对于键值在条件范围内但并不存在的记录(间隙),InnoDB 也会对这个"间隙"加锁
5、查看行锁争用情况
show status like 'innodb_row_lock%'
# Innodb_row_lock_current_waits: 当前正在等待锁定的数量
# Innodb_row_lock_time: 从系统启动到现在锁定总时间长度
# Innodb_row_lock_time_avg:每次等待所花平均时长
# Innodb_row_lock_time_max:从系统启动到现在等待长的一次所花的时间
# Innodb_row_lock_waits: 系统启动后到现在总共等待的次数
# 当等待的次数很高,而且每次等待的时长也不小的时候,我们就需要分析系统中为什么会有如此多的等待,
# 然后根据分析结果着手制定优化计划