一.事务

1.事务的特性

(1)原子性(Atomicity),可以理解为一个事务内的所有操作要么都执行,要么都不执行。

(2)一致性(Consistency),可以理解为数据是满足完整性约束的,也就是不会存在中间状态的数据,比如你账上有400,我账上有100,你给我打200块,此时你账上的钱应该是200,我账上的钱应该是300,不会存在我账上钱加了,你账上钱没扣的中间状态。

(3)隔离性(Isolation),指的是多个事务并发执行的时候不会互相干扰,即一个事务内部的数据对于其他事务来说是隔离的。

(4)持久性(Durability),指的是一个事务完成了之后数据就被永远保存下来,之后的其他操作或故障都不会对事务的结果产生影响。

2.事务的并发问题

(1)脏读:一个事务读取到另一个事务没有提交的数据

(2)不可重复读:同一事务中,两次读取同一数据,得到的内容不同

(3)幻读:同一事务中,用同样的操作读取两次,得到的记录数不同

3.事务的隔离级别

(1)读未提交:事务A可以读取到事务B未提交的数据

(2)读已提交:事务A只能读取其它事务已提交的数据(避免了脏读)

(3)可重复读:事务A只保存另一个事务做更新操作前的状态,保证另一个事务update时,当前事务的查询结果是一致的(避免了不可重复读)(mysql默认)

(4)序列化:事务串行化顺序执行(避免脏读 不可重复读 幻读)

二.锁

1.锁的类型

1.共享锁:(读锁)允许事务读一行数据

2.排他锁:(写锁)允许事务删除或更新一行数据

(共享锁之间是兼容的,而互斥锁与其他任意锁都不兼容)

2.锁的粒度

1.表锁

表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题

使用表级锁定的主要是MyISAM,MEMORY,CSV等一些非事务性存储引擎

MyISAM在执行查询前,会自动执行表的加锁、解锁操作,一般情况下不需要用户手动加、解锁,但是有的时候也需要显示加锁。比如:检索某一个时刻t1,t2表中数据数量。

LOCK TABLE t1 read, t2 read;
select count(t1.id1) as 'sum' from t1;
select count(t2.id1) as 'sum' from t2;
UNLOCK TABLES;

2.页锁

页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,页级锁定和行级锁定一样,会发生死锁。

使用页级锁定的主要是BDB存储引擎

3.行锁

行级锁定最大的特点就是锁定对象的粒度很小,所以发生锁定资源争用的概率也最小,并发性能好,但是容易发生死锁

使用行级锁定的主要是InnoDB存储引擎

3.InnoDB中的锁(表锁 行锁 意向锁)

  1. 意向锁

    innodb支持行锁和表锁。为了支持多粒度锁定,InnoDB 存储引擎引入了意向锁

    如果没有意向锁,当已经有人使用行锁对表中的某一行进行修改时,如果另外一个请求要对全表进行修改,那么就需要对所有的行是否被锁定进行扫描,在这种情况下,效率是非常低的;不过,在引入意向锁之后,当有人使用行锁对表中的某一行进行修改之前,会先为表添加意向互斥锁(IX),再为行记录添加互斥锁(X),在这时如果有人尝试对全表进行修改就不需要判断表中的每一行数据是否被加锁了,只需要通过等待意向互斥锁被释放就可以了。

    意向锁其实不会阻塞全表扫描之外的任何请求,它们的主要目的是为了表示是否有人请求锁定表中的某一行数据

    意向锁也分为两种:

    (1)意向共享锁(IS):事务想要在获得表中某些记录的共享锁,需要在表上先加意向共享锁。

    (2)意向互斥锁(IX):事务想要在获得表中某些记录的互斥锁,需要在表上先加意向互斥锁。

  2. 行锁的算法

    innodb有三种行锁的算法,分别是:

    (1)行锁(record lock):锁直接加在索引记录上面。锁住的是key(防止不可重复读)

    (2)间隙锁(gap lock):锁定索引记录间隙,确保索引记录的间隙不变。作用就是防止其他事务的插入操作,以此防止幻读的发生

    (3)后码锁(next-key Lock):行锁和间隙锁组合起来就叫Next-Key Lock。

    当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录

三.sql优化步骤

1.通过show status命令了解各种SQL的执行频率

show status like 'com_%'; //查询(增删改查等执行的次数.com_commit/rollback了解提交和回滚的情况,回滚频繁意味着编码可能存在问题)
show status like 'slow_query'; //查询慢查询的次数

2.定位执行效率较低的sql

在my.cnf 里 通过 log-slow-queries[=file_name]开启慢日志查寻

3.通过EXPLAIN分析较低SQL的执行计划

1.id

select识别符。我理解的事sql执行的顺序的标识

(1)id相同时,执行顺序由上至下

(2)如果是子查询,id序号会递增,id越大优先级越高,越先被执行

2.select_type

表示查询中每个select子句的类型

select_type查询类型 说明
SIMPLE 简单的 select 查询,不使用 union 及子查询
PRIMARY 最外层的 select 查询
SUBQUERY 在select或者where中包含了子查询,子查询中的第一个 select 查询,不依赖于外部查询的结果集
DEPENDENT SUBQUERY 子查询中的第一个 select 查询,依赖于外部 查询的结果集
DERIVED 用于 from 子句里有子查询的情况。MySQL 会递归执行这些子查询, 把结果放在临时表里
UNION UNION 中的第二个或随后的 select 查询,不 依赖于外部查询的结果集
DEPENDENT UNION UNION 中的第二个或随后的 select 查询,依 赖于外部查询的结果集
UNCACHEABLE UNION UNION 中的第二个或随后的 select 查询,属 于不可缓存的子查询

特别关注 DEPENDENT SUBQUERY ,会严重消耗性能,不会进行子查询,会先进行外部查询,生成结果集,再在内部进行关联查询。子查询的执行效率受制于外层查询的记录数

3.table

显示这一步所访问数据库中表名称(显示这一行的数据是关于哪张表的)

4.type

对表访问方式,表示MySQL在表中找到所需行的方式,又称“访问类型”

常用的类型有: ALL、index、range、 ref、eq_ref、const、system(从左到右,性能从差到好)

type 说明
ALL MySQL将遍历全表以找到匹配的行
index 遍历索引树
range 只检索给定范围的行,使用索引来选择行
ref 查找条件列使用了索引而且不为主键和unique。就是虽然使用了索引,但该索引列的值并不唯一,有重复。这样即使使用索引快速查找到了第一条数据,仍然不能停止,要进行目标值附近的小范围扫描
ref_eq 使用了主键或者唯一性索引进行查找
const 常量连接,表最多只有一行匹配,通用用于主键或者唯一索引比较时(where后面是逐渐或者唯一索引)
system 表中只有一行

5.possible_keys

预测用到的索引

6.key

实际用到的索引

7.key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度

8.ref

哪些列或者常量被用于查找索引列上的值(只有当type为ref的时候,ref这列才会有值)

explain select * from t1, t2 where t1.col1 = t2.col1 and t1.clo2 = 'ab';

ref的值为: t2.col1 ,"ab"

9.rows

估算的找到所需的记录所需要读取的行数

10.Extra

包含MySQL解决查询的详细信息

(1)Using filesort

mysql的排序方法主要分为两大类,一种是排序的字段是有索引的,因为索引是有序的,所以不需要另外排序,另一种是排序的字段没有索引,所以需要对结果进行排序,在这种情况下才会如上图所示显示一个Using filesort

eg:select * from a where a1="" order by a2; //a2没有建索引

(2)using temporary:性能损耗大,用到临时表(常见于group by)

eg:select * from a where a1="" group by a2

(3)using where:表明虽然用到了索引,但是没有索引覆盖,产生了回表。

select name,age from a where age="" //name需要回表查询

(4)using index:索引覆盖,查询的内容可以直接在索引中拿到

select age from a where age="" //索引覆盖

四.sql常用的优化方式

1.索引优化

注意索引失效的情况

(1)or连接的条件不是每一个列都有索引,这时有索引的列也会失效

(2)复合索引遵守“最左前缀”原则,即在查询条件中使用了复合索引的第一个字段,索引才会被使用

(3)like查询是以%开头(以%结尾,索引可以使用)

(4)存在索引列的数据类型隐形转换,则用不上索引(比如列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引)

(5)where 子句里对索引列上有数学运算,用不上索引

(6)where 子句里对有索引列使用函数,用不上索引

(7)如果mysql估计使用全表扫描要比使用索引快,则不使用索引(比如数据量极少的表)

2.设计调优

(1)数据量大,可以分库分表

(2)主从同步,读写分离

3.业务优化

根据具体业务场景进行优化

【总结】mysql调优的更多相关文章

  1. MySQL 调优/优化的 100 个建议

    MySQL 调优/优化的 100 个建议   MySQL是一个强大的开源数据库.随着MySQL上的应用越来越多,MySQL逐渐遇到了瓶颈.这里提供 101 条优化 MySQL 的建议.有些技巧适合特定 ...

  2. MySQL 调优基础(一) CPU与进程

    一般而言,MySQL 的调优可以分为两个层面,一个是在MySQL层面上进行的调优,比如SQL改写,索引的添加,MySQL各种参数的配置:另一个层面是从操作系统的层面和硬件的层面来进行调优.操作系统的层 ...

  3. MySQL调优系列基础篇

    前言 有一段时间没有写博客了,整天都在忙,上班,录制课程,恰巧最近一段时间比较清闲,打算弄弄MYSQL数据库. 关于MySQL数据库,这里就不做过多的介绍,开源.免费等特性深受各个互联网行业喜爱,尤其 ...

  4. mysql调优 基础

    MySQL调优可以从几个方面来做: 1. 架构层:做从库,实现读写分离: 2.系统层次:增加内存:给磁盘做raid0或者raid5以增加磁盘的读写速度:可以重新挂载磁盘,并加上noatime参数,这样 ...

  5. mysql调优最大连接数

    一.mysql调优 1.1 报错: Mysql: error 1040: Too many connections 1.2 原因: 1.访问量过高,MySQL服务器抗不住,这个时候就要考虑增加从服务器 ...

  6. MySQL调优 —— Using temporary

      DBA发来一个线上慢查询问题. SQL例如以下(为突出重点省略部分内容): select distinct article0_.id, 等字段 from article_table article ...

  7. 数据库MySQL调优实战经验总结<转>

    数据库MySQL调优实战经验总结 MySQL 数据库的使用是非常的广泛,稳定性和安全性也非常好,经历了无数大小公司的验证.仅能够安装使用是远远不够的,MySQL 在使用中需要进行不断的调整参数或优化设 ...

  8. MySQL调优 优化需要考虑哪些方面

    MySQL调优 优化需要考虑哪些方面   优化目标与方向定位 总体目标:使得响应时间更快,吞吐量更大. (throughout --- 吞吐量:单位时间内处理事务的数量) 如何找到需要优化的地方 使用 ...

  9. MySQL调优系列_日志分析

    前言 本篇主要总结一下MySQL数据库的几种日志,用于日常维护过程中问题解决和性能优化等,稍显基础,日常积累之用. 文章的部分内容会将MySQL数据库和SQL Server数据库部分内容做一个对比,非 ...

  10. MySQL 调优基础(四) Linux 磁盘IO

    1. IO处理过程 磁盘IO经常会成为系统的一个瓶颈,特别是对于运行数据库的系统而言.数据从磁盘读取到内存,在到CPU缓存和寄存器,然后进行处理,最后写回磁盘,中间要经过很多的过程,下图是一个以wri ...

随机推荐

  1. 浅谈Vue中计算属性computed的实现原理

    虽然目前的技术栈已由Vue转到了React,但从之前使用Vue开发的多个项目实际经历来看还是非常愉悦的,Vue文档清晰规范,api设计简洁高效,对前端开发人员友好,上手快,甚至个人认为在很多场景使用V ...

  2. 基于Huggingface使用BERT进行文本分类的fine-tuning

    随着BERT大火之后,很多BERT的变种,这里借用Huggingface工具来简单实现一个文本分类,从而进一步通过Huggingface来认识BERT的工程上的实现方法. 1.load data tr ...

  3. Matlab中fspecial的用法

    来源:https://blog.csdn.net/hustrains/article/details/9153553 Fspecial函数用于创建预定义的滤波算子,会与imfilter搭配使用,其语法 ...

  4. 如何查找一个为NULL的MYSQL字段

    前言:在做这个题目 https://www.cnblogs.com/pipihao/p/13786304.html 因为之前 我好像没有接触过什么 为NULL字段的查询,细节不小 WHERE 字段 I ...

  5. Oracle - ascii为0的陷阱

    一.概述 ascii0是个空字符,如果将这个字符插入到oracle数据库中会是什么现象,是null吗? 二.正式实验 创建一张测试表 create table test(id int, name va ...

  6. client: c#+protobuf, server: golang+protobuf

    前段时间看到一篇博文<可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)>,他是用C#实现的即时通讯系统,功能强大,界面漂亮. 就想用golang重写服务端,把代码下载 ...

  7. vue 组件的封装

    封装的原因 首先封装组件的需求肯定是多个地方要用到同一个东西,他们都有公共的地方,vue的封装 简单来说就是将公共参数封装起来 然后在需要的地方引入 //子组件封装 <template> ...

  8. 多测师讲解python __for 循环___高级讲师肖sir

    横向输出 1.遍历字符串 2.遍历列表 3.遍历元组 方法一: 方法二: 方法三: #循环字典:方法一# dict1={"name":"zhihao",&quo ...

  9. Spring系列 SpringMVC的请求与数据响应

    Spring系列 SpringMVC的请求与数据响应 SpringMVC的数据响应 数据响应的方式 y以下案例均部署在Tomcat上,使用浏览器来访问一个简单的success.jsp页面来实现 Suc ...

  10. idea创建servlet工程初体验

    servlet工程创建 前提:创建项目之前需要配置java环境变量 和tomcat配置,配置完成后进入如下操作. tomcat 安装和配置参考 https://www.cnblogs.com/xush ...