数据库

索引模块

1.为什么要使用索引

如果数据库中数据很多,使用全表扫描就很慢了。所以索引类似字典中将部首,偏旁组合起来去查询,就能快速查询数据

2.什么样的信息能成为索引

主键、唯一键以及普通键等

3.索引的数据结构

二叉查找树、B-Tree、B+-Tree、Hash结构

MySQL不支持BitMap

4.密集索引和稀疏索引的区别

密集索引文件中的每一个搜索码值对应一个索引值,即叶子节点不但需要保存键值,还保存位于同一行记录的其他列信息,一个表只能建立一个密集索引

稀疏索引只为搜索码的某些值建立索引项,即叶子节点只保存了键位信息以及该行数据的地址,有的稀疏索引只建立了键位信息及其主键

5.两种存储引擎

(1)Myisam

在MyISAM中 不管是主键索引 唯一键索引 普通索引 其索引都属于稀疏索引

(2)innodb

在Innodb中 有且仅有一个密集索引

(1)若一个主键被定义,该主键则作为密集索引

(2)若没有主键被定义,该表的第一个唯一非空索引则作为密集索引

(3)若不满足以上条件,Innodb内部会生成一个隐藏主键(密集索引)

(3)不同的引擎建立的文件

Myisam会建立三个文件:

test1.frm 存储表的结构信息

test1.MYI 存储表的索引信息

test1.MYD 存储表的数据信息

innodb会建立两个文件

test1.frm 存储表的结构信息

test1.ibd 存储表的索引信息和数据信息

如何定位并优化慢查询sql

经验问题,根据实际情况。提出大致思路

(1)根据慢日志定位慢查询sql(慢日志就是记录执行比较慢的sql查询)

打开慢查询日志 set global slow_query_log = on

设置慢查询时间 set global long_query_time = 1

(2)使用Explain等工具分析sql

Explain关键字段:

type :若为index或all,就是全表扫描的

extra:using filesort,using temporary 这两项意味着MySQL根本不能使用索引,效率会受到重大影响。 

(3)修改sql或者尽量让sql走索引

联合索引的最左匹配原则

联合索引:多列组成的索引

最左匹配原则:假设我们有两列a,b,a和b是联合索引,他的顺序是a,b,我们在where语句中调用a=? and b=?的时候就会走联合索引,如果调用where a = ?的时候也会走索引,但是当我们使用where b = ?的时候就不会走这个联合索引

成因:mysql创建复合索引的规则是首先会对复合索引的最左边,也就是索引中的第一个字段进行排序,在第一个字段排序的基础上,在对索引上第二个字段进行排序,其实就像是实现类似order by 字段1,字段2这样的排序规则,那么第一个字段是绝对有序的,而第二个字段就是无序的了,因此一般情况下直接只用第二个字段判断是用不到索引的,这就是为什么mysql要强调联合索引最左匹配原则的原因。

索引是建立得越多越好吗

(1)数据量小的表不需要建立索引,建立会增加额外的索引开销

(2)数据变更需要维护索引,因此更多的索引意味着更多的维护成本

(3)更多的索引意味着也需要更多的空间

B-Tree

1.B-Tree的定义

(1)根节点至少包含两个孩子

(2)每个节点最多有m个孩子

(3)除根节点和叶子节点外,其余每个节点都有ceil(m/2)个孩子

(4)所有叶子节点位于同一层

(5)

 B+-Tree

1.B-Tree和B+-Tree的区别:

(1)非叶子节点的子树指针与关键字个数相同

(2)非叶子节点仅用来索引,数据都保存在叶子节点中

(3)非叶子节点的指针P[i],指向关键字值[K[i],K[i+1])的子树

(4)所有叶子节点均有一个链指针指向下一个叶子节点

结论:

B+树更适合用来做磁盘索引

(1)B+树的磁盘读写代价更低

(2)B+树的查询效率更加稳定

(3)B+树更有利于对数据库的扫描

Hash索引

1.为什么不使用Hash索引?

(1)仅仅能满足”=“ ,”In“,不能使用范围查询

(2)无法被用来避免数据的排序操作

(3)不能利用部分索引键查询

(4)不能避免表扫描

(5)遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高

 数据库事务的四大特性

ACID

原子性

一致性:指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

         拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

隔离性:当多个用户访问同一个数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰。多个并发事务之间要隔离

持久性:一个事务一旦被提交了,那么对数据库中的数据的改变是永久性的

MyISAM与InnoDB关于锁方面的区别是什么

MyISAM默认使用的是表级锁,不支持行级锁

InnoDB默认用的是行级锁,也支持表级锁

MyISAM适合的场景:频繁执行全表count语句

            对数据进行增删改的频率不高,查询非常频繁

          没有事务

Innodb适合的场景:数据增删改查都相当频繁

         可靠性要求比较高,要求支持事务

数据库锁的分类

按锁的粒度划分:表级锁,行级锁,页级锁

按锁级别划分:共享锁,排他锁

按加锁方式划分:自动锁、显示锁

按操作划分:DML锁、DDL锁

按使用方式划分:乐观锁、悲观锁

事务并发访问引起的问题以及如何避免 事务隔离级别

更新丢失

 脏读------------------read committed级别及以上可以避免

不可重复读-----------------repeatable read级别及以上可避免

幻读--------------------------serializable事务隔离级别可避免

当前读和快照读

当前读:select...lock in share mode,select...for update,update,insert,delete

读取的是最新版本,并且读取时候还需要保证其他事务不能修改当前记录,对读取的事务加锁

快照读:不加锁的非阻塞读,select

在RR下,事务首次调用快照读的地方很关键

在RR级别下,快照读是通过MVVC(多版本控制)和undo log来实现的,当前读是通过加record lock(记录锁)和gap lock(间隙锁)来实现的。

innodb在快照读的情况下并没有真正的避免不可重复读(出现幻读,也导致了不可重复读), 但是在当前读的情况下避免了不可重复读和幻读!!! 

RR如何避免幻读

next-key锁:

行锁

Gap锁

原文地址:https://www.cnblogs.com/-2016/p/12561407.html