首页 > IT职业 > IT职场 > mysql 索引底层详解
+--------------+
| 客户端 |
+--------------+
↓
+--------------+
| 服务端 |
+--------------+
↓
+--------------+
| 存储引擎 |
+--------------+
当客户端需要查询一条sql时,在server端内部走了以下4步
+--------------+
| 连接器 |
+--------------+
↓
+--------------+
| 分析器 |
+--------------+
↓
+--------------+
| 优化器 |
+--------------+
↓
+--------------+
| 执行器 |
+--------------+
加了索引之后查询会更快,但是当数据量大的时候,增删改就会变慢;因为每次修改数据时除了数据本身,数据库还需要维护索引的那颗B+树;
索引都是存储在磁盘里面的,因为需要持久化存储,内存里也有,但都是每次查询时从磁盘加载到内存里的
无索引:没有索引的情况下,都会全表扫描,就是一条条地找,这无疑效率不高,又费io;
有索引:有索引的情况下,会为这个索引生成一颗B+树,有了这颗树的帮助,查询数据的效率会提升几千倍;
肯定不是啦,mysql和磁盘交互的时候是以页为单位进行传输的,默认情况下,每页大小为16K,,就像我们在电脑上新建一个txt文件,里面什么内容都没有,但它还是占用了4KB,mysql也一样,有自己的最小页大小,可通过 innodb_page_size 参数观看数据页大小
mysql> show variables like 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
要解决这个问题,我们就得先知道索引是怎么存储的
一个索引对应一个B+树,如果一张表建了10个索引,那就会有10个B+树,
OLAP联机分析处理—数据仓库–hive
对海量历史数据进行分析,产生决策性的影响
OLTP联机事务处理–关系型数据库
要求在很短的时效内返回对用的数据
hash索引不适合用来做数据库的结构,
答:有
create table (id bigint(20) primary key ,name varchar(10)) engine='innodb';
MySQL5.5版本之前,默认内置存储引擎是Myisam,
MySQL5.5版本之后,MySQL的默认内置存储引擎已经是InnoDB,
innodb只能有一个聚簇索引,但是有很多的非聚簇索引
+----------+
| 索引值 |
+----------+
| 数据 |
+----------+
+------------+
| 索引值 |
+------------+
|数据文件地址|
+------------+
一开始我的主键是id字段,那么在B+树中叶子节点的结构是这样的
+----------+
|主键索引值|
+----------+
| 数据 |
+----------+
这时候我又把name字段设置为索引了,这时候mysql为这个name索引也创建一颗B+树,这颗树的叶子节点存的就不是数据了,如果存数据的话会造成冗余,所以这个name索引树存的是主键id,就像这样
+----------+
| ye |
+----------+
/
+----------+ +----------+
| xin | | dong |
+----------+ +----------+
| 主键id | | 主键id |
+----------+ +----------+

向innodb插入数据的时候,必须要包含一个索引的key值,这个索引的key值,可以是主键,如果没有主键,就是唯一键,如果没有唯一键,那么就是一个自生成的6字节的rowid;
索引的创建跟存储引擎是挂钩的,存储引擎表示不同的数据在磁盘存储的文件格式也是不同的。
mysql常用的存储引擎有三个
innodb只能有一个聚簇索引,但是有很多的非聚簇索引,向innodb插入数据的时候,必须要包含一个索引的key值,这个索引的key值,可以使主见,如果没有主键,就是唯一键,如果没有唯一键,那么就是一个自生成的6字节的rowid;
因为主键只有一个,聚簇索引对应的就是主键字段,只有主键的索引B+树才会存储数据,其他的二级索引存储的都是主键的值;
如果每个二级索引树都存储数据的话,就会造成数据的冗余;
数据存储在: 你的mysql目录/data/db1/ 目录下,
其中,
查询语句为:show status like ‘Handler_read%’;
结果说明:
Handler_read_first 代表读取索引头的次数,如果这个值很高,说明全索引扫描很多。
Handler_read_key:代表一个索引被使用的次数,如果我们新增加一个索引,然后通过这个索引来查询数据,,可以查看Handler_read_key是否有增加,如果有增加,说明sql用到索引。这个数量越大越好,大表示索引查询使用的比较多;
Handler_read_next:代表读取索引的下列,按(主)键顺序依次读取之后的N行
Handler_read_last : 从(主)键的最后位置开始读取
Handler_read_prev: 代表读取索引的上列,一般发生在ORDER BY … DESC。
Handler_read_rnd: 代表在固定位置读取行,如果这个值很高,说明对大量结果集进行了排序、进行了全表扫描、关联查询没有用到合适的KEY。
Handler_read_rnd_next: 代表进行了很多表扫描,查询性能低下。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/1282/viewspace-2796775/ ,如需转载,请注明出处,否则将追究法律责任。