索引、事务与MySQL优化

一、索引

1.什么是索引

在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。

2.索引的作用

索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

3.索引建立在哪儿

建立在表上,是对表中一列或多列值进行排序的一种结构
索引和表中属性是有很大关系,要通过属性排序之后的结果建立结构

4.索引这样的结构放在哪儿

存储文件中
InnoDB:.frm 存储表的结构 .ibd 存储表中的数据和索引
MyIsam: .frm 存储表的结构 .myi: 存储索引 .myd:存储数据

5.索引的种类

普通索引
最基本的索引类型,没有唯一性之类的限制。普通索引可以通过以下几种方式创建:
创建索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表); [3]
创建表的时候指定索引,例如CREATE TABLE tablename ( […], INDEX [索引的名字] (列的列表) );
** 唯一索引 **
唯一索引是不允许其中任何两行具有相同索引值的索引。
当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。
例如,如果在 employee 表中职员的姓 (lname) 上创建了唯一索引,则任何两个员工都不能同姓。
对某个列建立UNIQUE索引后,插入新记录时,数据库管理系统会自动检查新纪录在该列上是否取了重复值,在CREATE TABLE 命令中的UNIQE约束将隐式创建UNIQUE索引。
创建唯一索引的几种方式:
创建索引,

CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表)

修改表,

ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表); 

创建表的时候指定索引

CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) )

全文索引
对文本的内容进行分词,进行搜索
** 单列索引 **

ALTER TABLE people ADD INDEX lname (lname);

将lname列建索引,这样就把范围限制在lname='Liu’的结果集1上,之后扫描结果集1,产生满足fname='Zhiqun’的结果集2,再扫描结果集2,找到 age=26的结果集3,即最终结果。
由于建立了lname列的索引,与执行表的完全扫描相比,效率提高了很多,但我们要求扫描的记录数量仍旧远远超过了实际所需 要的。
虽然我们可以删除lname列上的索引,再创建fname或者age 列的索引,但是,不论在哪个列上创建索引搜索效率仍旧相似。

** 多列索引 **

ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);

为了提高搜索效率
注意:上例中我们创建了lname_fname_age多列索引,相当于创建了(lname)单列索引,(lname,fname)组合索引以及(lname,fname,age)组合索引。
创建多列索引时要根据业务需求,把where子句使用最频繁的一列放在最左边
** 空间索引**
必须选择空间类型字段

6.索引的优缺点

  • 优点:提高查询速度
  • 缺点:由于索引也存储在文件中,索引多了数据相对少了
    频繁的修改表中的数据,也会造成索引结构的频繁修改(insert/update/delete)
    由于索引结构复杂维护消耗时间过多造成性能降低
    B+树(多路树):结构复杂

7.索引的设计原则

(1)数据量比较低的时候不需要建立索引。
(2)选择唯一性索引。属性是不重复的 ,索引价值百分之百 属性:建立索引时所选择的的那个属性
索引价值问题:索引价值=distinct(属性)/count(属性)
count(属性):属性总数
distinct(属性):属性是不重复的数量
(3)经常使用的属性上建立索引 建立索引的时候选择哪一个属性,只有使用时也选择那一个属于性

index(a)
	select * from user where b	>10;//用不上在a字段上建立索引
(4) 4,8 限制索引数目 删除不再使用或者很少使用的索引
(5) 5,7 针对在字符串类型上建立的索引而言   尽量使用数量少的索引
user name vachar(50) char text
		index(name(6));  //长度字段是影响比较结果,也就是影响B+树的结构
	还影响比较的时间:长度越长比较多的时间越长。
	abcdefg    最小
	abcdezca   第二小
	abcdezcf   最大

8.索引的创建

(1)在创建表的时候创建索引

//(1)普通索引:
	   create table index1(id int,
	                       name varchar(20),
						   sex boolean,
						   index(id)
						   );
		show create table index1;
		explain select * from index1 where id=1;
		//(2)创建唯一性索引
		create table index2(id int unique,
		                    name varchar(20),
							unique index index2_id(id asc)
							);
		//(3)创建全文索引
		create table index3(id int,
		                    info varchar(20),
							fulltext index index3_info(info)
							)engine=MyIsam;
		//(4)创建单列索引
		create table index4(id int,
		                    subject varchar(30),
							index index4_(subject(10))
							);
		//(5)创建多列索引
		create table index5(id int,
		                    name varchar(20),
							sex char(4),
							index index4_ns(name,sex)
							);
		//(6)创建空间索引
		create table index6(id int,
		                    space geometry not null,
							spatial index index6_sp(space)
							)ENGINE=MyISAM;

(2)在已存在的表上创建索引

        (1)普通:create index index7 on 表名 (id);
		(2)唯一:create unique index index8 on 表名(course_id);
		(3)全文:create fulltext index index9_info on index9(info);
		(4)单列:create index index10_addr on 表名(address(4));
		(5)多列:create index index11_na on 表名(name,address);
		(6)空间:create spatial index index12_line on 表名(line);

(3)用Alter Table语句来创建索引

        (1)普通:alter table 表名 add index index13_name(name(20));
		(2)唯一:alter table 表名 add unique index index14_id(course_id);
		(3)全文:alter table 表名 add fulltext index index15_info(info);
		(4)单列:alter table 表名 add index index16_addr(address(4));
		(5)多列:alter table 表名 add index index17_na(name,address);
		(6)空间:alter table 表名 add spatial index index18_line(line);

9.索引的数据结构

9.1B树索引

9.1.1 MyISAM B树索引
  • 主键索引(索引建立在主键上)
    MySql会默认创建主键索引 所有的表一定会右主键
    create table table1(id int primary key);
  • 辅助索引(索引建立在非主属性上)
    与主键索引形式相同
    多列辅助索引

  • 比较原则:从左往右比 最左比较法
    先比较第一个属性,如果第一个属性值相同在比较第二个属性
    先以第一个属性建立B+树 如果第一个属性值相同在以第二个属性建立B树
    叶子节点存储:建立索引的属性和数据对应的地址(不论是单列还是多列索引)
    MyISAM下的索引称作:非聚簇(聚集)型索引无非就是建立索引的属性从一个变成了多个

  • 文件; .myI
    要将B+树的结构加载到内存中才能使用
    **注意:**并不是将整个B+树的结构加载到内存, 而是一个结点一个结点的加载
    首先应该加入内存的就是根节点,剩下的就要根据大小比较后的结果判断应该再去加载哪一个结点
    叶子结点:存储的是主键(建立索引的属性)和数据地址
    **MyISAM:**数据和索引分在两个文件中存储 索引:.myi 数据:.myd

//id(主键)  name  age
	index(name,age);
	select age from student where name=Bob;  //只查询一次B+树,就能查询出来
	select name from student where age=18; 用不到的
	index(name)
	select age from student where name=Bob;  //查询两次  一次是查询B+树 第二次是根据地址找数
9.1.2 InnoDB B树索引
  • 主键索引(索引建立在主键上):
    MySql会默认创建主键索引
    叶子节点存储:主键和所有的数据,数据和索引在同一个文件下 。数据和索引都存储在.idb文件下
    • 辅助索引(索引建立在非主属性上)叶子节点存储,建立索引的的属性和和它对应的主键的值
      InnoDB下的索引聚簇(聚集)型索引
    • 聚集和非聚集的区别:
      叶子节点存储的是数据本身还是数据地址
   select*from user where 主键 =10;

InnoDB查询一次就可以,原因是主键索引的叶子节点存储主键和这个主键对应的所有数据
MyISAM:查询两次 原因:叶子节点存储建立索引的属性和数据的地址,还需要根据有地址再去查询出
所有的数据。

 select * from user where 主键 =10

如果MyISAM也要只查询一次那么必须建立联合索引

index(id,age); //叶子节点存储:id age 还有数据的地址
   index(name)
   select age from user where name ="Bob"
  • InnoDB:查询两次
    第一次是在name所建立的B+树上去查找数据 叶子节点存储name的值和name对应的主键的值
    第二次是根据主键的值去主键索引这棵B+树上查找所有的数据的值最终把age的值返回
  • MyISAM:查询两次
    第一次;name的索引树
    第二次:根据查出的地址在去找所有的数据
  • 两个引擎下索引的区别:
    (1)主键索引: InnoDB 叶子节点存储之间和主键对应的数据所有的值
    MyISAM叶子节点存储主键和主键对应的数据的地址
    (2) 辅助索引: InnoDB叶子节点存储建立索引的是属性的值和这个属性对应的主键的值
    MyISAM 叶子节点存储建立索引的是属性的值和这个属性对应数据地址
9.1.2 Memory B树索引

树——> 二叉树——>排序二叉树——>多路树——>B树——>B+树
B树的特点 如果我们定义M为B树的分支数量 M肯定是大于2的 最小就是3
1.定义任意非叶子结点最多只有M个儿子
2.根节点所存储的数据为1~M-1,根结点的儿子数为(2,M )
3.除根结点外的非叶子结点的儿子数为(M/2,M)
4.每个结点存放至少M/2-1 (取上整)和至少M-1个关键字 (至少2个关键字)
5.非叶子结点的关键字个数(结点中存储的数据数量)=指向儿子的指针个数(分支数量)-1
6.非叶子结点和叶子结点均存储数据

9.2 B+树索引

  • B+树特点
    其定义基本与B-树相同
    除了:
    1.非叶子结点的子树指针与关键字个数相同 结点存储的数据数量和它的分支数量相同
    2.B+树只在叶子结点存储数据
    3.为所有叶子结点增加一个链指针:连成了一个链表 这张链表是有序的
    如何使用B+树作为索引结构
    那么MySQL最终为什么要采用B+树存储索引结构呢,那么看看B—树和B+树在存储结构上有什么不同?
    1.B-树的每一个结点,存了关键字和对应的数据地址,而B+树的非叶子结点只存关键字,
    不存数据地址,因此B+树的每一个非叶子节点存储的关键字是远远多于B-树的,
    B+树的叶子结点存放关键字和数据,因此,从树的高度上来说,B+树的高度小于B-树的,
    使用的磁盘I/O次数少,因此查询会更快一些。
    2.B-树由于每个节点都存储关键字和数据,因此离根节点近的数据,查询的就快,离根节点远的数据
    查询的就慢; B+树所有的数据都存在叶子结点上,因此在B+树上搜索关键字,找到对应数据的时间是比较平均的
    没有快慢之分
    3.在B-树上如果做区间查找,遍历的节点是非常多的: B+树所有的叶子结点被连接成了有序链表结构,
    因此做整表遍历和区间查找是非常容易的。

    二 、事务

    1.什么是事务

    • 一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元)
    • 一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成
    • 事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同

    2.用sql语句实现转账操作

range(主键)  money
	A:  1             50   

	B:  1             100
		2             300
		B ---> A 转账 50块  
update  B set money = 60  where range = 1;  //多出10块
update  A set money = 100 where range = 1;

3.red log日志与undo log日志

  • mysql 通过 redo log 日志保证了数据的持久性。
  • mysql通过undo log 日志保证了可以rollback。(回滚)
    作用和redo log相反,在sql语句执行的时候会记录一条和你要执行的sql作用相反的
    sql语句
    当执行insert语句时,undo log日志中回记录对应的delete 语句,
    当执行delete,记录对应的insert语句
    执行update 语句记录 相反的update语句
    当你执行rollback时,可以读取undo log 日志然后回滚数据。
    当我们执行commit(提交)之后就会对undo log 日志进行数据清空,此时如果在想rollback
    就不行了。

4.关于事务的操作

  • 开启事务:set autocommit = 0;
  • 提交事务:Commit
  • 回滚事务:Rollback

5.当多个用户同时进行操作时出现的问题

  • 脏读(Dirty Read):(事务B读取了事务A尚未提交的数据)
    一个事务读取了另一个事务未提交的数据。
    例如当事务A和事务B并发执行时,当事务A更新后,事务B查询读取到A尚
    未提交的数据,此时事务A回滚,则事务B读到的数据就是无效的脏数据。
  • 不可重复读(NonRepeatable Read): (事务B读取了事务A已提交的数据)
    一个事务的操作导致另一个事务前后两次读取到不同的数据。
    例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A更新操作更改事务B查询到的数据,此时事务B再次去读该数据,发现前后两次读的数据不一样。
  • 虚读(Phantom Read)/幻读:(事务B读取了事务A新增加的数据或者读不到事务A删除的数据)
    一个事务的操作导致另一个事务前后两次查询的结果数据量不同。
    例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一条满足事务B查询条件的记录,此时事务B再去查询,发现查询到前一次不存在的记录,或者前一次查询的一
    些记录不见了。

6.事务的特性(ACID)

  • 事务的原子性(Atomic):
    rollback; 原子性的实现原理 ——》Undo log
    事务是一个不可分割的整体,事务必须具有原子特性,及当数据修改时,要么全执行,要么全不执行,即不允许事务部分的完成。

  • 事务的一致性(Consistency):如果其他三个特性能够保证,一致性一定可以保证事务的一致性实现原理 = 原子性原理 + 隔离性原理 + 持久性原理
    一个事务执行之前和执行之后,数据库数据必须保持一致性状态。
    数据库的一致性状态必须由用户来负责,由并发控制机制实现。就拿网上购物来说,你只有让商品出库,又让商品进入顾客的购物车才能构成一个完整的事务!由于并发操作带来的数据不一致性包括读脏数据(脏读),不可重复读和虚读(幻读)。

  • 事务的隔离性(Isolation):
    4个隔离级别 隔离性实现原理:mysql锁机制 + MVCC机制
    事务的隔离性:分级别的 不同级别的隔离性解决不同的问题。 根据不同场景设置不同的隔离级别。
    只要将隔离级别设置正确上述三个问题就轻松解决了。
    不同的隔离级别解决不同的问题:
    隔离级别

隔离级别 脏读 不可重复读 虚/幻读
不支持事务
未提交读 可以 可以 可以
已提交读 不可以 可以 可以
可重复读 不可以 不可以 可以
串行化 不可以 不可以 不可以

  1. TRANSACTION_NONE。 表示不支持事务
  2. TRANSACTION_READ_UNCOMMITTED。未提交读。
    说明在提交前一个事务可以看到另一个事务的变化。这样读”脏”数据,不可重复读和虚读都是被允许的。
  3. TRANSACTION_READ_COMMITTED。已提交读。
    说明读取未提交的数据是不允许的。这个级别仍然允许不可重复读和虚读产生。
  4. TRANSACTION_REPEATABLE_READ。可重复读。
    说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。
  5. TRANSACTION_SERIALIZABLE。可序列化/串行化。
    MVCC机制
    是最高的事务级别,它防止读脏数据,不可重复读和虚读。
    多版本并发控制(MVCC,Multiversion Currency Control)。 所谓的mvcc机制就是尽量的不去使用这些锁,一旦这些锁加上之后事务与事务之间就变成了完全的串行执行,在隔离级别中串行化其实就是这样做的。MVCC的实现,是通过保存数据在某一个时间点的快照作为每个事务操作数据的并且记录为一个版本,每一个事务只操作自己版本下的数据。因此每一个事务无论执行多长时间看到的数据,都是一样的。
    MyIsam:
    当操作数据时,MyIsam引擎下锁住的是整张表,所以称之为锁表
    作用于数据。数据存在某一张表中。
    InnoDB:
    既支持行锁又支持表锁
    • 行锁:操作的数据肯定在表中的某一行或者某一行,那么如果只锁住这某几行数据就是行锁分为 读锁和写锁
      读读不互斥 读写互斥 写写互斥
      select 对数据不造成修改的操作——读操作 读锁
      update insert delete 对数据造成改变操作——写操作 写锁
      1个查看用户余额 1个 修改余额
      互斥:只能有一个成功
      select * from user where id >=10 and id <=15;
      for update 想让这条sql获取到写锁但是我又不希望数据修改
      (1)表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
      (2)行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
      (3)页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般 当两个或者多个事务并发执行时,为了保证数据的安全性,将一个事物内部的操作与其它事务的操作隔离起来,不被其它正在执行的事务所看到。
      例如对任何一对事务T1和T2,
      对T1而言,T2要么在T1开始之前已经结束,要么在T1完成之后
      再开始执行。隔离性使得每个事务的更新在它被提交之前,
      对其它事务都是不可见的。
      让我们看看事务处理之父Jim Gray对事务隔离性的定义[1]:
      Isolation: Concurrently executing transactions see the stored information as if they were running serially (one after another).
  • 事务的持久性(Durability):
    持久性的实现原理 redo log 事务完成以后,DBMS保证它对数据库中的数据的修改是永久性的,即使数据库因为故障出错,也应该能够恢复数据!

7.事务的实现原理

实际上只要说清楚每种性质的实现原理即可
学习这些原理之前我们要先知道MySQL的Buffer Pool机制。
InnoDB作为MySQL的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘IO,效率会很低。为此,InnoDB提供了缓存(Buffer Pool),Buffer Pool中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲:当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool;当向数据库写入数据时,会首先写入Buffer Pool,Buffer Pool中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)。Buffer Pool的使用大大提高了读写数据的效率,但是也带了新的问题:如果MySQL宕机,而此时Buffer Pool中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证,所以我们需要使用mysql中的日志来保证数据持久性的

7.1持久性实现原理:redo log 日志

当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求。

7.2原子性实现原理:undo log 日志 rollback; commit;

**undo log**中会记录一条和你执行的sql语句意义相反的sql语句,当你rollback时就执行undo log中的sql语句。

实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。InnoDB实现回滚,靠的是undo log:当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。undo log属于逻辑日志,它记录的是sql执行相关的信息。当发生回滚时,InnoDB会根据undo log的内容做与之前相反的工作:对于每个insert,回滚时会执行delete;对于每个delete,回滚时会执行insert;对于每个update,回滚时会执行一个相反的update,把数据改回去。以update操作为例:当事务执行update时,其生成的undo log中会包含被修改行的主键(以便知道修改了哪些行)、修改了哪些列、这些列在修改前后的值等信息,回滚时便可以使用这些信息将数据还原到update之前的状态

7.3Mysql隔离性的实现原理:锁机制 + MVCC机制:

• Record Locks(记录锁):在索引记录上加锁。

  • Gap Locks(间隙锁):在索引记录之间加锁,或者在第一个索引记录之前加锁,或者在最后一个索引记录之后加锁。
    • Next-Key Locks:在索引记录上加锁,并且在索引记录之前的间隙加锁。它相当于 是Record Locks与Gap Locks的一个结合

共享读锁和排他写锁:
• 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
• 排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的。

行锁和表锁:
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
• 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最 低,并发度也最高

MVCC机制:
所谓的mvcc机制就是尽量的不去使用这些锁,一旦这些锁加上之后事务与事务之间就变成了完全的串行执行,在隔离级别中串行化其实就是这样做的。这里又要涉及到我们之前所学的乐观锁和悲观锁。

InnoDB的一致性的非锁定读就是通过在MVCC实现的,Mysql的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制(MVCC)。MVCC的实现,是通过保存数据在某一个时间点的快照来实现的,,每一个事务只操作自己版本下的数据。因此每一个事务无论执行多长时间看到的数据,都是一样的。所以MVCC实现可重复读。

把这些机制了解清楚之后,我们来说一下隔离性实现的原理。首先隔离性一共分了4种隔离级别。分别是:未提交读,已提交读,可重复读,和序列化。

已提交读(Read committed):
在RC级别中,数据的读取都是不加锁的,但是数据的写入、修改和删除是需要加锁的(Record Locks)。那么已提交读时如何解决脏读问题的?这个就利用了mvcc机制。
只要没有commit那么修改就是自己版本下的数据。

可重复读(Repeatable read):
数据的读取都是不加锁的,但是数据的写入、修改和删除是需要加锁(Record Locks)的+Mvcc机制
即使commit操作的也是自己版本数据。

序列化(Serializable):所有锁都加了 没有mvcc机制 效率最低
这个级别很简单,读加共享锁,写加排他锁,读写互斥。使用的悲观锁的理论,
(加的锁就是Next-Key Locks)实现简单,数据更加安全,但是并发能力非常差。如果你的业务并发的特别少或者没有并发,同时又要求数据及时可靠的话,可以使用这种模式。由于InnoDB引擎加的是行锁,并且是加在索引记录上,所以为了不产生幻读在还会加间隙锁。
串行。

7.4一致性实现原理

持久性+隔离性+原子性共同实现了数据的一致性。

8.事务的操作

1.得有表和数据 存储引擎:切换到InnoDB
2.开启事务 :相当于是自己控制提交的时间。
由于Mysql在敲下sql语句按下回车之后会自动提交所以第一步开启事务实际上就是关闭自动提交机制。
3.可通过SELECT @@AUTOCOMMIT; 查看MySQL是否已经关闭自动提交。
mysql> select @@autocommit;
±-------------+
| @@autocommit |
±-------------+
| 1 | # 0表示手动提交事务 1表示自动提交事务
±-------------+
1 row in set (0.01 sec)

4.如果未关闭,可使用SET AUTOCOMMIT = 0操作;设置事务提交方式为手动提交事务

5.BEGIN 或 START TRANSACTION 显式地开启一个事务;(可写可不写)
6.COMMIT; 当组成事务的所有sql语句都执行成功,调用commit提交一个事务
7.ROLLBACK; 如果在执行事务的过程当中有一个事务执行失败回滚一个事务到初始的位置commit 和 rollback 事务结束的两种方式。
10条sql 第8条出错
8.SAVEPOINT point1; 设置一个名字为point1的保存点
9.ROLLBACK TO point1; 事务回滚到保存点point1,而不是回滚到初始状态
10. set session transaction isolation level READ COMMITTED; 设置事务的隔离级别
如下4种分别对应,我们之前讲过的4种隔离级别
Read uncommitted 、Read committed 、Repeatable read 、 Serializable 序列化
11.查询事务的隔离级别
mysql> select @@tx_isolation;
±----------------+
| @@tx_isolation |
±----------------+
| REPEATABLE-READ | // MySQL默认工作在“可重复读”的隔离级别 重启恢复默认
±----------------+
1 row in set (0.00 sec)

三、MySQL优化

1.书写合适sql语句:

索引和数据缓存 索引存在文件
explain 发现sql语句用到索引 如果是使用索引的过程比较耗时
MyIsam: key_buffer_size=8M 索引缓存
innodb_buffer_pool_size=8M 索引和数据缓存

2.增加连接池。作用:重复使用连接(对象)。

如果是因为频繁的创建销毁连接耗时
用户量非常大 100W, 1 创建连接 执行sql 释放连接

3.增加缓存池(redis数据库缓存级数据库)。

  • 减少了文件IO(特别耗时)的次数
  • 对数据查询修改次数过于频繁。

4.修改MySQL的查询缓存,但是在使用查询缓存的时候需要注意。

query_cache_type=0 关闭缓存
query_cache_type=1 开启缓存
query_cache_size=10 改变缓存大小 改变配置文件中的数据,记得重启服务。
对数据查询修改次数过于频繁。

5.MySQL线程缓存:CPP C/S 系统 客户端服务器 网络连接

C / S :cpp epoll+ 线程池 ---- 处理任务 线程池中存储的就是线程
** 线程的作用: **处理具体任务。 工人
** 线程池 : ** thread_cache_size=10
我们之前就提到过MySQL如果不在我们自己的服务器上的时候,我们要进行远程访问。既然要远程访问就离不开网络模型。MySQL所使用的是epoll+ 线程池的模型。这个线程中存放的是能够处理具体任务的线程,当有SQL请求到达MySQL Server的时候,在线程池中取一个线程来执行该SQL请求就可以了,执行完成后,不销毁线程,而是把线程再归还到线程池中,等待下一次任务的处理(当然MySQL会根据用户量,自动加大线程池的数量的)。和MySQL建立连接时出现的问题:

6.调整MySQL最大连接量的大小 151

当我们发现由于最大连接数量过低 导致有大量用户无法建立连接。
show variables like ‘%connect%’;
max_connections=151

7.连接超时时间

如果设置连接超时时间过低,用户建立连接速度过慢。就会出现有一些用户无法和mysql正常建立连接。
show global variables like ‘%timeout%’;
在配置文件中添加配置:wait_timeout=600。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值