MySQL入门详解(二)---mysql事务、锁、以及优化
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在一个商城系统中,用户执行购买操作,那么用户订单中应该加一条,库存要减一条,如果这两步由于意外只进行了其中一步那么就会发生很大的问题。而事务可以很好的解决这个问题。
事务是数据库处理操作,其中执行就好像它是一个单一的一组有序的工作单元。换言之在组内每个单独的操作是成功的,那么一个事务才是完整的。如果事务中的任何操作失败,整个事务将失败。
事务性质:
原子性:确保工作单位中所有操作都成功完成;否则,事务被中止,在失败时会回滚到事务操作以前的状态。
一致性:可确保数据库在正确的更改状态进行一个成功的提交事务。
隔离性:使事务相互独立的操作。
持久性:确保了提交事务的结果或系统故障情况下仍然存在作用。
TCL(事务控制语言):
begin;
操作;
commit; BEGIN或START TRANSACTION; #显式地开启一个事务
COMMIT;或COMMIT WORK; #二者等阶。COMMIT会提交事务并使已对数据库进行的所有修改成为永久性的。未COMMIT的操作都存放在内存中,仅当前客户端可以查看到,其他客户端看不到,当前客户端关闭后就清空了
ROLLBACK;或ROLLBACK WORK; #二者等阶。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改
SET AUTOCOMMIT= #禁止自动提交 隐式开启事务
SET AUTOCOMMIT= #开启自动提交
事务并发的问题:
1.脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
2.不可重复读:事务A多次读取同一数据,事务B在事务A多次读取过程中,对数据作了更新并提交 ,导致事务A多次读取同一数据时结果不一致
3.幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条没有改过来,就好像发生了幻觉一样
各个隔离级别情况:
#查看隔离级别
select @@session.tx_isolation;
#设置隔离级别
set session transaction isolation level read uncommitted
隔离级别 | 脏读可能性 | 不可重复读可能性 | 幻读可能性 |
未提交读 READ UNCOMMITED | 是 | 是 | 是 |
不可重复读 READ COMMITED | 否 | 是 | 是 |
可重复读 REPEATABLE READ | 否 | 否 | 是 |
串行化 SERIALIZABLE | 否 | 否 | 否 |
数据库锁
mysql不同存储引擎支持不同锁机制,innodb支持表行级锁默认行级锁,memory采用表级锁,bdb采用页面锁支持表级锁。
表级锁:开销小,加锁快,不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。不支持事务。
页面锁:开销和加锁时间介于前后者之间,会出现死锁;锁定粒度介于前后者之间,并发度一般。
行级锁:开销大,加锁慢,会出现死锁;锁定粒度小,发生锁的冲突概率最低,并发度也最高。
表级锁:两种模式 共享锁(读锁)与独占锁(写锁,排他锁),表级锁引擎:MyISAM MEMORY
- 共享锁:在读的时候上锁,所有人都可以访问不阻塞其他用户对同一表读请求,但阻塞同一表的写操作包括自己;自己如果加了读锁,更新访问其他表会提示错误;加了读锁之后不能再加写锁
- 独占锁:上锁之后其他人不能访问,阻塞其他用户对同一表的读和写操作,独占锁优先级别高于共享锁;自己加了写锁可以读写表中记录,但更新访问其他表都会提示错误
MyISAM在执行查询语句时会自动给涉及的所有表加读锁,在执行更新操作前加写锁,这个过程一般不需要用户干预。
#加锁
lock tables table_name read [local];lock tables table_name write [local];
#多表加锁
lock tables table_name [table_name] read [local];lock tables table_name [table_name] write [local];
#释放锁
unlock tables;
#查询表级锁争用情况
show status like 'table%';
show status like '%lock%';当waited immediate值比较大是说明阻塞严重
show processlist; #查看哪些sql在在等待锁
show open tables; #当前被锁住的表以及锁的次数
#并发插入
myisam存储引擎有一个系统变量concurrent_insert.专门用以控制其并发插入行为,其值为NEVER0、AUTO1(默认)、ALAWAYS2。
:不允许并发插入 ,:如果表中没有空洞(表中没有被删除的行)myisam允许在一个进程读表的同时,另一个进程从表尾插入记录,:无论表中有没有空洞,都允许在表尾插入记录
#读写锁优先级
max_write_lock_count= #设置写锁的最多次数,当系统处理一个写操作后就会暂停写操作给读操作执行机会
#降低写操作优先级,给读操作更高优先级
low_priority_updates= sql_low_priority_updates= 在用写操作时要加low_priority关键字#视场景而定,读场景更重要或更多时如此设置
如何优化表所?
concurrent_insert设置2,总是允许并发插入,但是要定期OPTIMIZE TABLE整理空间碎片;视情况设置写优先级;视情况设置写内存,解决批量插入数据(如新闻系统更新)场景中。
行级锁:引擎InnoDB,模式包含 共享锁(S),排它锁(X),意向共享锁(IS),意向排它锁(IX) 如果一个事务请求的锁模式与当前的锁兼容,innoDB就将请求的锁授予该事物;反之,如果两者不兼容,该事物就要等待锁释放
行级锁特点:innoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件(例如id)检索数据,innoDB才使用行级锁,佛则将使用表锁;意向锁是innoDB自动加的,不需要用户干预,对于写操作(insert update delete)innodb会自动给涉及数据加排它锁,对于select InnoDB不会加任何锁
排它锁(X) | 意向排它锁(IX) | 共享锁(S) | 意向共享锁(IS) | |
---|---|---|---|---|
排它锁(X) | 冲突 | 冲突 | 冲突 | 冲突 |
意向排它锁(IX) | 冲突 | 兼容 | 冲突 | 兼容 |
共享锁(S) | 冲突 | 冲突 | 兼容 | 兼容 |
意向共享锁(IS) | 冲突 | 兼容 | 兼容 | 兼容 |
#加锁
SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE #主动添加共享锁(S)
SELECT * FROM table_name WHERE ... FOR UPDATE #主动添加独占锁(X) #释放锁
commit;或
rollback;
- 当使用行排他锁写数据时,其他人无法操作本条数据;
- 当给一条数据添加了排它锁,其他人对这条数据没有任何权限,但并不影响其他人对其他数据操作;
- 在InnoDB默认的隔离方式下,操作者不提交,操作数据只保存在内存里,另一用户可以查询,查询到的是旧值;
- 即使字段家里索引在使用时自己变了类型,索引失效会加表锁;
间隙锁:比如有124三个数据,操作>1的数据,此时添加3或者5都是不可以的,所以要明确范围防止间隙锁
如何优化行级锁:
- 尽量使用较低的隔离级别(新手忽略);精心设计索引,并尽量使用索引访问数据,使加锁更精确从而减少锁冲突的机会
- 选择合理的事务大小,小事务发生锁冲突的几率也小
- 给记录集手动加锁时,最好一次性请求足够级别的锁
- 尽量使用相等条件访问数据,这样可以避免间隙锁对并发插入的影响
- 对于一些特定事务,可以使用表锁提高速度并减少死锁可能
数据库优化操作
优化成本 硬件>系统配置>数据库表结构>SQL语句及索引
优化效果 SQL语句及索引<数据库表结构<系统配置<硬件
MySQL逻辑架构:
客户端->连接线程处理->查询缓存、分析器、优化器->存储引擎
索引底层实现:B树
myisam存储是数据的地址 innodb存储的是索引值,所以索引不宜过长
explain参数详解:
select语句执行顺序:执行顺序:先where...group by ... having 再 select ... from ... 再 distinct ... order by ... limit ...
#使用方式:
explain select * from demo;
#参数:
#id 执行顺序
id相同时顺序从被查询表数据量少至多(都一样的话按照书写顺序),子查询时id由外到里自增,先执行大的
#select_type 查询中每个select子句的类型
SIMPLE:简单SELECT(不使用UNION或子查询)
PRIMARY:最外面的SELECT
UNION:UNION中的第二个或后面的SELECT语句
DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
UNION RESULT:UNION 的结果
SUBQUERY:子查询中的第一个SELECT
DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
DERIVED:派生表(FROM子句的子查询)
#table 本次查询的表名,或派生表
#type mysql在表中的访问类型
ALL: 遍历全表,目标不带索引
<
index: 遍历全表索引树
<
range: 检索给定范围的有索引的行,between、<、>,不能用in会使索引失效
<
ref: 检索给定具体值并有索引的行
<
eq_ref: 检索给定具体值并是唯一索引的行
<
const: 表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数
<
system: 衍生查询中只有一条数据
<
NULL
#possible_keys 本查询可能用的索引
#key 本查询真实用的索引
#key_len 索引在内存中占的长度(轻易不要给varchar加索引)
#ref 指定的条件类型
#rows 当前语句查到的行数
#Extra
Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
range checked for each record (index map: ):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。
Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息,代表性能不错
Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。
Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户,性能一般
Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。
IMPOSSIBLE :不可能的where语句如where id= and id=
mysql优化方法:
- 通过使用explain命令分析sql语句的运行效率
- 通过开启慢查询日志查看效率慢的sql语句
单多表sql优化手段:
- 给使用频繁的字段加索引,调整索引顺序最佳左前缀原则,删除多余干扰索引,调整查询条件对索引有干扰的语句放最后
多表sql额外优化手段:
- 小表驱动大表(小表在左边,where小表.x=大表.y)
- left join 给左边表加索引,right join 给右边表加索引
注意:
- 不要将索引作为函数参数或表达式的一部分,这样会让索引失效;索引不要进行类型转化否则失效
- 复合索引应该遵循最佳左前缀,不要用or,in,!= < >关键字否则失效
- 及时删除冗长,不常用的索引
- like查询时尽量不要使用左边%引起索引失效
系统级别优化:
- 主从复制,读写分离,负载均衡
其他优化:
- 选尽量小的数据类型,列设置not null,加unsigned不允许加正负这样可以使正数上线多一倍,存储时间最好用TIMESTAMP使用4个字节存储,大多数情况下没有枚举类型的必要,表的列不要太不要超过10个字段多影响内存数据类型小而简单
MySQL入门详解(二)---mysql事务、锁、以及优化的更多相关文章
- Mysql入门详解
目录 数据库之Mysql 一 .简单了解数据库 二.Mysql的使用 三.多表查询 数据库之Mysql 本篇文章为观看某教学视频后所作个人总结 一 .简单了解数据库 1.1常见关系型数据库 mysql ...
- c++操作mysql入门详解
首先,根据你当前的操作系统,还有开发工具,选择相应的mysql版本.本人选择的环境是win10 + vs2013 需要解决三个问题:1.下载安装mysql服务器,并登录mysql测试一下是否安装成功: ...
- MySQL系列详解二:MySQL语句操作-技术流ken
简介 本篇博客将详细讲解mysql的一些常用sql语句操作,例如创建数据库,删除数据库,创建表,修改表,删除表,以及简单查询案例. 关于mysql数据中的SQL的大小写问题 1.不区分大小写 1. s ...
- MySQL入门详解(一)---mysql的语言
MySQL语言分为:DCL(数据库控制语言).DDL(数据库定义语言).DQL(数据库查询语言).DML(数据库操作语言),这一节我们先从mysql的语言开始. DCL:数据库控制语言,用来设置数据库 ...
- MySQL入门详解(三)---mysql如何进行主从配置
基本要求 两台服务器(windows,linux,mac) 双方mysql版本需一致,如不一致,只要主节点低于从节点 两台服务器防火墙关闭 双方数据库所用的用户,要具有远程访问的权限 主服务器配置 修 ...
- MySQL Explain详解 查看mysql语句详情
在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有 ...
- MySQL存储过程详解 mysql 存储过程(二)
mysql存储过程详解 1. 存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL ...
- MySQL配置文件详解
MYSQL 配置文件详解 “全局缓存”.“线程缓存”,全局缓存是所有线程共享,线程缓存是每个线程连接上数据时创建一个线程(如果没有设置线程池),假如有200连接.那就是200个线程,如果参数设定值是1 ...
- 转:JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法、shiro认证与shiro授权
原文地址:JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法.shiro认证与shiro授权 以下是部分内容,具体见原文. shiro介绍 什么是shiro shiro是Apache ...
随机推荐
- 修改windows远程默认端口
修改windows远程默认端口 windows端口修改rdp 1 远程服务器运行窗口调出注册表编辑器 注册表编辑器regeidt 2 修改两个注册表 1,在注册表HKEY_LOCAL_MACHINE\ ...
- Spring 全局异常处理
[参考文章]:Spring全局异常处理的三种方式 [参考文章]:Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理 [参考文章]:@ControllerAdvic ...
- OS之内存管理 --- 虚拟内存管理(二)
关于虚拟内存管理之前的请看:OS之内存管理 - 虚拟内存管理(一) 帧分配 每个进程对的最小帧数是由操作系统的体系结构决定的,但是最大帧数是由可用物理内存的数量决定的.所以在这之间,对于进程的帧的分配 ...
- vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件
vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...
- 轮播图采用js、jquery实现无缝滚动和非无缝滚动的四种案例实现,兼容ie低版本浏览器
项目源代码下载地址:轮播图 以下为项目实现效果:(由于gif太大,所以只上传一张图片,但效果完全能实现,经测试,在ie各版本浏览器及chrome,firefox等浏览器中均能实现效果,可以实现点击切换 ...
- Java生成某段时间内的随机时间
上代码: import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { /** * 生成随机时间 ...
- ASP.NET Core 1.0 中使用 Log 日志配置
https://github.com/aspnet/Logging https://docs.asp.net/en/latest/fundamentals/logging.html ASP.NET C ...
- 在Android中调用KSOAP2库访问webservice服务出现的服务端返回AnyType{}
最近在做毕业设计的时候,涉及到了安卓端访问web service服务端数据库,并返回一个值,当我把web service测试通过后,想写一个简单的安卓测试程序,来实现服务端数据库访问,通过web se ...
- Linux信号和trap命令的使用
目录 信号介绍 信号列表 控制信号 Ctrl+c显示指定内容 使Ctrl+c无任何操作 处理多个信号 处理所有信号 恢复信号 实现跳板机(实例) 信号介绍 运行Shell脚本时,如果按下快捷键Ctrl ...
- Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二):数据库设计
数据库设计 系统主要包含用户(sys_user).组织(sys_dept).角色(sys_role).菜单(sys_menu).角色组织(sys_role_dept).角色菜单(sys_role_me ...