++++++++++++++++事务,索引,锁
B+树索引
一、为什么要用索引?
1. 什么是索引
是一种帮助mysql提高查询效率的数据结构
在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。
2.索引的优点
大大加快数据查询速度 3)索引的缺点
3.索引的缺点
维护索引需要耗费数据库资源
索引需要占用磁盘空间
当队标的数据进行增删改的时候,因为要维护索引,速度会受到影响
如何维护索引,因为索引在存储数据时是顺序存储的,所以在增删改查的时候,得需要维护索引的位值
4.没有索引的时候如何访问数据
使用平衡二叉树索引访问数据
注:不同存储引擎的横向对比
特点 | MySAM | BDB | Memory | InnoDB |
---|---|---|---|---|
存储限制 | 没有 | 没有 | 有 | 64TB |
事务安全 | 支持 | 支持 | ||
锁机制 | 表锁 | 页锁 | 表锁 | 行锁 |
B树索引 | 支持 | 支持 | 支持 | 支持 |
哈希索引 | 支持 | 支持 | ||
全文索引 | 支持 | |||
集群索引 | 支持 | |||
数据缓存 | 支持 | 支持 | ||
索引缓存 | 支持 | 支持 | 支持 | |
数据可压缩 | 支持 | |||
空间使用 | 低 | 低 | N/A | 高 |
内存使用 | 低 | 低 | 中等 | 高 |
批量插入的速度 | 高 | 高 | 高 | 低 |
支持外键 | 支持 |
二、InnoDB数据的存储方式
如何修改存储引擎
Alter table tableName engine =engineName
在InnoDB存储引擎中, 所有数据都存放在表空间中,表空间由段(segment),区(extent)、页(page)、行(Row)组成一个InnoDB数据页的存储结构:一个页的大小16KB
名称 | 占用空间大小 | 简单描述 |
---|---|---|
文件头部 | 38 | 页的一些通用信息(Page指针,双向链表) |
页面头部 | 56 | 数据页专有的一些信息 |
最大、最小记录 | 26 | 两个虚拟的行记录(select用) |
用户记录(data) | 不确定 | 实际存储的行记录内容(单链表) |
空闲空间 | 不确定 | 页中尚未使用的空间 |
页面目录 | 不确定 | 页中的某些记录的相对位置(主键位置) |
文件尾部 | 8 | 校验页是否完整 |
如果建表时不指定主键,数据库会拒绝建表的语句执行。 事实上, 一个加了主键的表,并不能被称之为「表」。一个没加主键的表,它的数据无序的放置在磁盘存储器上,一行一行的排列的很整齐, 跟我认知中的「表」很接近。如果给表上了主键,那么表在磁盘上的存储结构就由整齐排列的结构转变成了树状结构,也就是上面说的「平衡树」结构,换句话说,就是整个表就变成了一个索引。没错, 再说一遍, 整个表变成了一个索引,也就是所谓的「聚集索引」。 这就是为什么一个表只能有一个主键, 一个表只能有一个「聚集索引」,因为主键的作用就是把「表」的数据格式转换成「索引(平衡树)」的格式放置。
聚簇索引
- “聚簇”的意思是数据行被按照一定顺序一个个紧密地排列在一起存储。一个表只能有一个聚簇索引,因为在一个表中数据的存放方式只有一种。
- 以innodb为例,在一个数据table中,它的数据文件和索引文件是同一个文件。即在查询过程中,找到了索引,便找到了数据文件。在innodb中,即存储主键索引值,又存储行数据,称之为聚簇索引。
- innodb索引,指向主键对数据的引用。非主键索引则指向对主键的引用。innodb中,没有主见索引,则会使用unique索引,没有unique索引,则会使用数据库内部的一个行的id来当作主键索引。
- 在聚簇索引中,数据会被按照顺序整理排列,当使用where进行顺序、范围、大小检索时,会大大加速检索效率。非聚簇索引在存储时不会对数据进行排序,相对产生的数据文件体积也比较大。
- 一个叶子结点就是一整行数据
非聚簇索引
则可能是通过其他算法规则构成的一种索引结构,索引的结构和实际数据存储的结构是不同的,比如说这张图中的索引类型就属于非聚簇索引;
二级索引
就是在除了主键索引之外定义的索引
主键索引是按顺序存储的,二级索引是随机存储的
联合索引
多个列组合起来进行索引
mysql优化:
尽量让数据顺序读写,少让数据随机读写
主键要有序
索引的使用
- 一个索引就是一个B+树,索引让我们的查询可以快速定位和扫描到我么你需要的数据记录,加快查询的速度
- 一个select查询语句在执行过程中一般最多能使用一个二级索引,即使在where条件中用了多个二级索引
- 不管用哪个索引扫描区间只有一个
范围区间的扫描:
只要索引列和常数使用=、<=>、IN、NOT IN、IS NULL、IS NOT NULL、>、<、>=、<=、BETWEEN、!=或者LIKE操作符连接起来,就可以产生所谓的扫描区间。
- IN 可以产生多个单点扫描区间 in(a,b)那么a和b就都是单点扫描区间
- LIKE ‘b%’ 和 LIKE‘%b’ 区别
这个只有第一种情况才会用到索引,而第二种情况是不会用到索引的,因为扫描区间不好定义
对于某个索引列来说,字符串前缀相同的记录肯定是相邻的- !=产生的扫描区间比较有趣,也容易被大家忽略,比如:SELECT * FROM single_table WHERE key1 != ‘a’; 此时使用idx_key1执行查询时对应的扫描区间就是:(-∞, ‘a’)和(‘a’, +∞)。
边界条件 就是相当于扫描区间的最大和最小值