MySQL


事务、隔离性

数据库事务四大特性:原子性(Atomicity)、隔离性(Isolation)、持久性(durability)、一致性(consistency)

原子性

指事务中的操作必须像原子一样,不可分割,要么全部成功,要么全部失败,可以通过undolog来实现。

隔离性

指多个事务在执行时相互隔离,在事务并发执行时,有三种场景:读与读、读与写、写与写,此时可能出现四种问题:

丢失更新(Last To Modify)

事务A执行了更新操作,但未提交,事务B也执行了更新操作,也未提交,接着事务A执行提交,事务B执行提交,此时,事务A的更新会被事务B的更新所覆盖掉,发生丢失更新

脏读(Dirty Read)

事务B执行了更新操作,而事务A读取到了未提交的数据,而未提交的数据存在两种结果:1.被提交 2.被回滚,当事务B执行了回滚操作,事务A读取到的数据即脏数据,行为被称为脏读

不可重复读(Unrepeatable Read)

当事务A进行了两次读取操作,而在这两次读取操作之间,另一个事务B对数据进行了修改,从而导致事务A两次读取到的数据不一致,出现不可重复读

幻读(Phantom Read)

例如事务A对表中所有数据进行了修改,而事务B在之后插入数据,接着事务A进行读取数据,发现存在有未修改的数据,就好像产生了幻觉一样,因此被称为幻读

为了避免以上情况的发生,SQL提供了四种事务隔离级别:

读未提交(Read Uncommitted)

一个事务还未提交,所做的操作是可以被其它事务读取到的,丢失更新的解决是数据库层面上的,所以读未提交可以解决丢失更新

读已提交(Read committed)

一个事务所做的操作必须等提交之后才能被别的事务所读取到,即未提交的操作是不可见的,读已提交可以解决丢失更新、脏读问题

可重复读(Repeatable Read)

一个事务在其执行的期间所读取到的数据都是一致的(除了自身修改),读已提交可以解决丢失更新、脏读、不可重复读,该隔离模式为MySQL的默认模式

可串行化(Serializable)

可串行化为事务隔离级别最高的,同时也是并发性能最低的,所有的操作都会进行加锁,当出现锁冲突时,只能等待

丢失更新 脏读 不可重复读 幻读
读未提交
读已提交
可重复读
可串行化

持久性

指事务一旦提交或回滚,数据的改变是永久的,通过redo log实现。

一致性

事务完成时,数据必须符合预期结果,当实现原子性、隔离性、持久性,一致性就能够实现。


索引

索引的作用是改善数据库表查询速度的一种数据结构,可以指定一个列或者多个列来创建索引,MySQL索引是在存储引擎层实现的。索引的结构有多种,最常见的是以B+Tree为结构,MySQL的默认引擎InnoDB、MyISAM、Memory都支持,另外还有Hash结构,底层由hash table实现,但这种结构不支持范围查询,Memory引擎支持改结构,以及MyISAM支持的主要用于索引多维信息的R-tree结构和通过倒排索引实现的全文索引。

索引可以分为主键索引、唯一索引、常规索引、全文索引,其中主键索引只有一个。

MySQL的InnoDB引擎的索引可以分为聚集索引(Clustered Index)和二级索引(Secondary index),二级索引又可以称为非聚集索引和辅助索引。聚集索引中键值的逻辑顺序决定了数据的物理顺序,而物理顺序只有一种情况,因此聚集索引有且仅有一个,数据与索引放到一起,叶子结点保存了行数据。如果存在主键,主键索引就是聚集索引,如果不存在主键,则选取第一个unique索引作为聚集索引,否则InnoDB默认选择或者添加一个隐藏列作为主键索引。

索引的设计原则

1.针对数据量较大,查询比较频繁的表建立索引。

2.针对常作为条件操作的字段建立索引

3.尽量建立唯一索引,区分度越高,索引的效率越高

4.如果是长字符串,可以建立前缀索引

5.尽量使用联合索引,联合索引很多时候可以覆盖索引,避免会变查询

6.控制索引的数量,索引越多,维护的成本就越大


SQL性能分析

为什么需要性能分析?如果希望对数据库进行优化,必须知道可以优化的地方,可以从以下三个方面进行:慢查询日志ProfileExplain

慢查询日志

慢查询日志记录了MySQL中响应时间超过阀值long_query_time的sql语句,该阀值的默认值为10,即运行时间超过10秒的sql语句将被记录到慢查询日志。慢查询日志默认不开启,我们可以查看慢查询日志是否开启

show variables like 'slow_query_log'

通过my.cnf文件可以开启慢查询,也可以选择临时启用

set global slow_query_log = 1

更改阀值时间

set global long_query_time = second

具体的信息可以通过slow_query.log文件查看

Profile

Profile可以分析sql语句执行的系统资源消耗情况,可以通过Profile查看sql语句的执行时间、CPU开销、块IO开销等信息,Profile默认是不开启的。

开启profiling

set profiling = 1

查看profiling

show profiling

通过指定query_id来查看sql语句的具体情况

show profile for query id
Explain

Explain可以用来分析sql查询语句的执行计划,在查询语句前面添加explain即可。

其返回信息字段为:

字段
id
select_type
table
partitions
type
possible_keys
key
key_len
ref
rows
filtered
extra

文章作者: tang ran
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 tang ran !
  目录