mysql索引和存储引擎

mysql索引为什么采用B+树而不用B树

(1)B+树只有叶节点存放数据,其余节点用来索引,而B树是每个索引节点都会有Data域(索引放磁盘中,磁盘IO就会增多)

(2) B+树所有的Data域在叶子节点,并且所有叶子节点之间都有一个链指针。这样遍历叶子节点就能获得全部数据,这样就能获得区间访问了。在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作。

 

 

mysql中Myisam和InnoDB都是使用B+树

Myisam和InnoDB的区别:(https://www.jb51.net/article/157181.htm)

(1)默认存储引擎的变迁:在5.1之前使用的是Myisam,5.5之后变成了InnoDB

(2)Myisam表级锁,不支持事务和全文索引,使用大并发,重负荷生产系统上,表级锁结构性能不好,InnoDB行级锁,事务安全(ACID),支持外键,5.6.4之后支持全文索引

(3)Myisam和InnoDB性能测试,随着CPU核数的增加,InnoDB的吞吐量反而越好,而MyISAM,其吞吐量几乎没有什么变化,显然,MyISAM的表锁定机制降低了读和写的吞吐量。

(4)事务支持与否,Myisam是一种非事务的引擎,使得数据库可以提供高速的存储和检索,以及全文搜索能力,适合频繁查询的操作,InnoDB是事务安全的,中间哪个环节出现问题都可以回滚,Myisam不可以

(5)构成上的区别,每个MyISAM在磁盘上存储成三个文件,.frm文件存储表定义,数据文件,其扩展名为.MYD (MYData),索引文件,其扩展名是.MYI (MYIndex),

 

mysql中最小的存储单位是页(可以减少磁盘io)

页目录(就是B+tree)

等价于(下图B+tree)(主键索引,叶子节点是整行的数据)

聚集索引(主键索引)和辅助索引(二级索引)

聚集索引(主键索引)

聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的记录数据。

聚集索引的叶子节点称为数据页,聚集索引的这种特性决定了索引组织表中的数据也是索引的一部分。

辅助索引(二级索引)

非主键索引,叶子节点=键值+书签,Innodb存储引擎的书签就是相应行数据的主键索引值(111,222是数据行中的三列创建的索引值,1是主键值)(此时如果查询不是索引列,查询用到了索引,就需要回表,通过主键值,查询主键索引中的值(也叫回表))

 覆盖索引

(1)就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖

myisam存储引擎底层是三个文件:frm(表结构)myi(索引文件),myd(数据文件)

myisam叶节点存储的是索引和数据节点的磁盘地址,查询数据需要回表,比Innodb相对来说性能差点

 

 

 

 

https://www.cnblogs.com/wezheng/p/8399305.html(索引的链接,创建原则)

 索引创建的原则:

1)对于查询频率高的字段创建索引

2)对排序,分组,联合查询频率高的字段创建索引

3)索引的数目不宜太多(每创建一个索引都会占用相应的物理控件,过多的索引会导致insert,update,delete语句的执行效率降低)

4)若在实际中,需要将多个列设置索引时,可以采用多列索引。

5)选择唯一性索引(唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。如:学号)

6)尽量使用数据量少的索引

7)尽量使用前缀来索引

8)删除不再使用或者很少使用的索引

mysql - 索引最左前缀的解释

在创建一个n列的索引时,遵循“最左前缀”原则:

1)必须用到索引的第一个字段

eg: create index iN_AAA_1 on AAA (a, c);

select * from AAA where b=:xxx and c=sysdate;则不会用到索引,因为必须有a出现在where 语句中才会使用到该索引(跟出现在where中的位置先后没有关系)

2)对于索引的第一个字段,用like时左边必须是固定值,通配符只能出现在右边。

eg:select * from AAA where a like '1%';会用到索引;而select * from AAA where a like '%1';不会用到索引。

3)如果在字段前加了函数,则索引会被抑制

eg:select * from aaa where trim(a)=1,则不会用到索引。

4)在字段前嵌入了表达式,索引也将被抑制。

eg:where a+7<sysdate将不会用到索引,而where a<sysdate-7会用到索引。

还有两个特殊声明:
1).select * from AAA where a=:xxx and c=sysdate与 select * from AAA where c=sysdate and a=:xxx;都会用到索引,即与where语句中字段出现的顺序无关;

2).select * from AAA where a=:xxx and b=1;会使用索引,此时A出现,即使其他字段不是索引字段也会使用到索引。

mysql的锁

表锁和行锁

读锁(共享锁)

写锁(排他锁)

 

InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面带来了性能损耗可能比表锁会更高一些,但是在整体并发处理能力方面要远远高于MyISAM的表锁的。当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显的优势。但是,InnoDB的行级锁同样也有其脆弱的一面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可能会更差。

优化建议:

(1)尽可能让所有数据检索都能通过索引来完成,避免无索引行锁升级为表锁。

(2)合理设置索引,尽量缩小锁的范围

(3)尽可能较少索引条件,及索引范围,避免间隙所

(4)尽量控制事务大小,减少锁定资源量和时间长度

(5)尽可使用低级别事务隔离(但是需要业务层面满足需求)

 

posted @ 2020-05-25 15:39  hulifang  阅读(408)  评论(0编辑  收藏  举报