一、为什么要用索引?
二、什么是索引?
三、MySQL索引使用场景
四、索引的原理
五、MySQL的存储引擎
六、索引的数据结构
七、索引如何使用
八、实际使用示例
九、优缺点、使用建议和注意事项
十、为什么Mysql不选择Hash索引?
十一、总结
索引,可能让好很多人望而生畏,毕竟每次面试时候 MySQL 的索引一定是必问内容,哪怕先撇开面试,就在平常的开发中,对于 SQL 的优化也而是重中之重。 为什么要用索引呢?
提高查询性能:索引可以减少数据库查询时需要扫描的行数,通过直接访问索引来快速定位所需数据,从而加快查询速度。
加速排序和分组:索引可以帮助加速ORDER BY和GROUP BY操作,减少排序和分组的时间消耗。
加速连接操作:当进行连接查询时,索引可以帮助优化连接操作的效率,减少连接操作的时间。
提高数据唯一性和完整性:通过在列上创建唯一索引或主键索引,可以确保数据的唯一性和完整性,避免重复数据或无效数据的存在。
减少磁盘IO和系统负载:通过使用索引,可以有效减少磁盘IO操作和系统负载,提高系统的整体性能。
索引是数据库管理系统中用于提高查询速度的一种数据结构。在MySQL中,索引可以看作是一种特殊的表,其中包含了对数据表中特定列的值及其在数据表中的位置信息。通过使用索引,MySQL可以在不需要扫描整个表的情况下快速找到与查询条件匹配的记录。
在MySQL中,主要有以下几种类型的索引:
以下是一些常见的索引使用场景:
大表查询优化:对于包含大量数据的表,使用索引可以大幅提高查询速度。
主键和外键约束:在创建主键和外键约束时,MySQL会自动创建相应的索引,以确保数据的唯一性和引用完整性。
范围查询和排序:对于范围查询和排序操作,使用B-Tree索引可以显著提高查询效率。
文本数据模糊查询:对于文本数据的模糊查询,使用全文索引可以提高查询速度。
MySQL官方对索引定义:是存储引擎用于快速查找记录的一种数据结构。需要额外开辟空间和数据维护工作。
索引的基本原理:
数据是以文件的形式存放在磁盘上面的,每一行数据都有它的磁盘地址,如果没有索引的话,我们要从千万行数据里面检索一条数据,只能依次遍历这张表的全部数据,直到找到这条数据。但是我们有了索引之后,只需要在索引里面去检索这条数据就行了,因为它是 特殊的专门用来快速检索的数据结构,我们找到数据存放的磁盘地址以后,就可以拿到数据了。
存储引擎是MySQL的组件,用于处理不同表类型的SQL操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。
使用哪一种引擎可以灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,使用合适的存储引擎,将会提高整个数据库的性能 。
MySQL服务器使用可插拔的存储引擎体系结构,可以从运行中的 MySQL 服务器加载或卸载存储引擎 。
-- 查看支持的存储引擎
show engines;
-- 查看默认存储引擎
SHOW VARIABLES LIKE 'storage_engine'
--查看具体某一个表所使用的存储引擎,这个默认存储引擎被修改了!
show create table tablename
--准确查看某个数据库中的某一表所使用的存储引擎
show table status like 'tablename'
show table status from database where name="tablename"
-- 建表时指定存储引擎。默认的就是INNODB,不需要设置
CREATE TABLE t1 (i INT) ENGINE = INNODB;
CREATE TABLE t2 (i INT) ENGINE = CSV;
CREATE TABLE t3 (i INT) ENGINE = MEMORY;
-- 修改存储引擎
ALTER TABLE t ENGINE = InnoDB;
-- 修改默认存储引擎,也可以在配置文件my.cnf中修改默认引擎
SET default_storage_engine=NDBCLUSTER;
索引的定义:索引(Index)是帮助MySQL高效获取数据的排好序的数据结构。
索引中常见的数据结构有以下几种:
Hash表
二叉树
红黑树
B-Tree
B+Tree
通过索引的key进行一次hash计算,就可以快速获取磁盘文件指针,对于指定索引查找文件非常快,但是对于范围查找没法支持,有时候也会出现Hash冲突的情况。
二叉树的特点:左边子节点的数据小于父节点数据,右边子节点的数据大于父节点数据。如下图所示,如果col2是索引,查找索引为65的行元素,只需要查找两次,就可以获取到行元素所在的磁盘指针地址。
但如果是一个按照顺序递增的值,例如为col1建立索引,不再适合使用二叉树建立索引,因为此时使用二叉树建立索引将会变成一个链式索引,此时的索引结构如下图所示,如果查找6节点需要6次遍历才能找到。
红黑树是一种二叉平衡树,可以提高查询效率,此时若再查找6节点只需要遍历3次就能找到了。但红黑树也有缺点,当存储大数据量时,树的高度就会变的不可控, 数量越大,树的高度越高,查询的效率将会大大降低。
B-Tree是一种多路二叉树,所具有的特点:1 叶节点具有相同的深度,叶节点的指针为空;2 所有索引元素不重复;3 节点中的数据索引从左到右递增排列。
B+Tree是B-Tree的变种,所具有的特点:1 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引;2 叶子节点包含所有索引字段;3 叶子节点用指针连接,提高区间访问的性能。
与红黑树相比,B-Tree和B+Tree两种数据结构都更加矮胖,存储相同数量级的索引数据时,层级更低。
B-Tree和B+Tree之间一个很大的不同,是B+Tree的节点上不储存value,只储存key,而叶子节点上储存了所有key-value集合,并且节点之间都是有序的。这样的好处是每一次磁盘IO能够读取的节点更多,也就是树的度(Max.Degree)可以设置的更大一些,因为每次磁盘IO读取的磁盘页数是一定的。例如,每次磁盘IO能够读取1页=4kb,那么省去value的情况下同样一页数据能够读取更多的key,这样就大大减少了磁盘的IO次数。
此外,B+Tree也是排好序的数据结构,数据库中><或者order by等都可以直接依赖这一特性。
MySQL中对于索引使用的主要数据结构也是B+Tree,目的也是在读取数据时能够减少磁盘IO。
在MySQL中,创建索引有以下几种方法:
在创建表时创建索引:在创建表时,可以使用INDEX
、UNIQUE INDEX
、PRIMARY KEY
或FOREIGN KEY
关键字创建索引。
示例:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE,
email VARCHAR(255) UNIQUE,
age INT,
INDEX (age)
);
在已有表上创建索引:可以使用CREATE INDEX
或CREATE UNIQUE INDEX
语句创建索引。
示例:
CREATE INDEX idx_age ON users (age);
CREATE UNIQUE INDEX idx_email ON users (email);
使用ALTER TABLE创建索引:可以使用ALTER TABLE
语句添加或删除索引。
示例:
ALTER TABLE users ADD INDEX (age);
ALTER TABLE users DROP INDEX idx_age
假设我们有一个用户表users
,表结构如下:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE,
email VARCHAR(255) UNIQUE,
age INT
);
现在,我们将演示如何使用索引优化以下查询:
根据ID查询用户:在这种情况下,我们可以使用主键索引加速查询。
示例:
SELECT * FROM users WHERE id = 123;
根据用户名查询用户:在这种情况下,我们可以使用唯一索引加速查询。
示例:
SELECT * FROM users WHERE username = 'john';
根据年龄范围查询用户:在这种情况下,我们可以使用B-Tree索引加速查询。
示例:
SELECT * FROM users WHERE age BETWEEN 18 AND 25;
为了加速此查询,我们需要为`age`列创建一个索引:
CREATE INDEX idx_age ON users (age);
提高查询速度:索引可以显著提高数据库查询速度。
确保数据唯一性和引用完整性:通过使用主键和外键索引,可以确保数据的唯一性和引用完整性。
增加存储空间和维护成本:索引会占用额外的存储空间,并增加数据更新和维护的成本。
影响写操作性能:由于在插入、更新和删除操作时需要维护索引,索引可能会降低写操作的性能。
选择合适的索引类型:根据查询需求选择合适的索引类型,如B-Tree索引、哈希索引、空间索引或全文索引。
为常用查询列创建索引:根据实际查询需求,为常用查询条件和排序列创建索引。
避免过度索引:过多的索引可能会降低写操作性能并占用额外的存储空间。在创建索引时,要权衡查询优化和空间、性能成本。
定期评估索引效果:通过使用慢查询日志、性能监控工具和EXPLAIN
语句,定期评估索引的效果并调整索引策略。
Hash索引的优势是精确查找的话,速度会更快,为什么不选择Hash索引