1.什么是索引?
索引是帮助Mysql高效获取数据的一种数据结构 (排好序的快速查找的数据结构)
本质上,索引是一种 数据结构
索引的目的在于提高查找效率,类比字典
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。
注:一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的方式存储在磁盘上🤷♂️索引也是需要排序的,并且这个排序的算法和TreeSet一致
索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
建立索引会占用磁盘空间的索引文件。
2.索引的内部实现方法
在任何数据库当中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号
在Mysql中,索引是一个单独的对象,不同的存储引擎以不同的形式存在,在MyISAM中,索引存储在.MYI文件中,在Innodb存储引擎中,索引存储在一个逻辑名称叫做tablespace当中,在MEMORY当中,索引被存储在内存中
不管索引存在哪里,索引都是以一棵树的形态进行存储(自平衡二叉树B-Tree)🧂
3.什么时候适合添加索引?
数据量庞大(根据硬件配置情况而定)此字段经常出现在where后面,以条件的形式存在该字段很少的DML操作(DML操作之后,索引需要重新排序)索引的添加适可而止,请不要没有节制的添加索引字段❌
4.索引的创建和删除创建索引:
mysql> create index temp_ename_index on temp(ENAME); Query OK, 0 rows affected (0.15 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> desc temp; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | EMPNO | int(4) | NO | | NULL | | | ENAME | varchar(10) | YES | MUL | NULL | | | JOB | varchar(9) | YES | | NULL | | | MGR | int(4) | YES | | NULL | | | HIREDATE | date | YES | | NULL | | | SAL | double(7,2) | YES | | NULL | | | COMM | double(7,2) | YES | | NULL | | | DEPTNO | int(2) | YES | | NULL | | +----------+-------------+------+-----+---------+-------+ 8 rows in set (0.00 sec)
删除索引:explain用于解析执行sql语句😊
mysql> drop index temp_ename_index on temp; Query OK, 0 rows affected (0.07 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> explain select * from temp where ename = "KING"; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | temp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 10.00 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
5.索引失效
第一式:
select * from emp where ename like '%T';
注意:模糊查询以%开头,不会进行索引查询,此时索引会失效
尽量避免模糊查询以%开头!
第二式:
使用or的情况,必须要求or两边的条件字段都要有索引,否则两边的索引都会失效
尽量少使用or进行查询!🧂
第三式:
使用复合索引查询时,没有使用左侧的列查找,索引会失效
首先介绍一下复合索引的添加方法:
mysql> create index temp_ename_job_index on temp(ename,job); Query OK, 0 rows affected (0.14 sec) Records: 0 Duplicates: 0 Warnings: 0
使用左侧字段进行查找的时候,会使用到索引:
mysql> explain select * from temp where ename = "KING"; +----+-------------+-------+------------+------+----------------------+----------------------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+----------------------+----------------------+---------+-------+------+----------+-------+ | 1 | SIMPLE | temp | NULL | ref | temp_ename_job_index | temp_ename_job_index | 33 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+------+----------------------+----------------------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
没有使用左侧的列查找,索引会失效:
mysql> explain select * from temp where job = 'MANAGER'; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | temp | NULL | ALL | NULL | NULL | NULL | NULL | 14 | 10.00 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.02 sec)
第四式:
在索引列中参加的运算,索引会失效🤞
第五式:
在where中索引列使用了函数
…
6.索引分类
单一索引:一个字段中添加了索引
复合索引:两个字段或者更多字段添加索引
主键索引:主键上添加索引
唯一性索引:具有unique约束的字段上添加索引
路遥知马力,索引高级篇见!