索引: 帮助mysql提高查询效率的数据结构。
索引的优点:
索引的缺点:
索引分类:
-- 主键索引在创建表的时候自动创建
CREATE TABLE `t_user` (
`id` INT(19) PRIMARY KEY,
`name` VARCHAR(20)
);
-- 查看表的索引
SHOW INDEX FROM `t_user`;
-- 建表之后新建普通索引
CREATE INDEX `name_index` on `t_user`(`name`);
-- 删除表
DROP TABLE `t_user`;
CREATE TABLE `t_user` (
`id` INT(19) PRIMARY KEY,
`name` VARCHAR(20),
KEY(`name`) #创建表时创建普通索引
);
-- 删除表
DROP TABLE `t_user`;
CREATE TABLE `t_user` (
`id` INT(19) PRIMARY KEY,
`name` VARCHAR(20),
UNIQUE(`name`) #创建表时创建唯一索引
);
-- 删除索引
DROP INDEX `name` ON `t_user`;
-- 建表之后新建唯一索引
CREATE UNIQUE INDEX `unique_index` ON `t_user`(`name`);
复合索引注意事项:
name
查、基于name age
查、基于name,age,length
查,其他组合都不能使用name
就能查,但只有name,length
的话就只能用到name
-- 删除表
DROP TABLE `t_user`;
CREATE TABLE `t_user` (
`id` INT(19) PRIMARY KEY,
`name` VARCHAR(20),
`age` INT(3),
`length` DOUBLE,
KEY(`name`,`age`,`length`) #创建表时创建复合索引
);
-- 删除联合索引,删一个就能全部删掉
DROP INDEX `name` ON `t_user`;
-- 建表之后创建联合索引
CREATE INDEX `key_index` ON `t_user`(`name`,`age`,`length`);
InnoDB支持的:a,b,c,d
创建一个主键索引的表,再乱序插入数据,查看表
CREATE TABLE `t_user` (
`id` INT(19) PRIMARY KEY,
`name` VARCHAR(20),
`length` DOUBLE
);
-- 乱序插入数据
INSERT INTO `t_user` VALUES(5,'qing',1.7);
INSERT INTO `t_user` VALUES(9,'song',1.8);
INSERT INTO `t_user` VALUES(1,'qiu',1.5);
INSERT INTO `t_user` VALUES(3,'chen',1.9);
INSERT INTO `t_user` VALUES(6,'hu',1.4);
INSERT INTO `t_user` VALUES(8,'zhao',1.7);
INSERT INTO `t_user` VALUES(4,'wang',1.8);
SELECT * FROM `t_user`;
是为了快速查询
了解B树和B+树的文章
B+树与B树最大的区别: B树非叶子结点必须存储数据,B+树只有叶子结点存储数据。
聚簇索引: 将数据存储和索引放到一起,索引结构的叶子结点保存了行数据(如:主键索引)。
非聚簇索引: 将数据与索引分开储存,索引结构的叶子结点指向了数据对应的位置。
注意: 在innodb中,在聚簇索引之上创建的索引称之为辅助索引,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引。辅助索引叶子节点存储的不再是行的物理位置,而是主键值,辅助索引访问数据总是需要二次查找。
问:辅助索引为啥不直接存地址,而是存id?
答:当发生增删改之后,物理地址会变化,且主键占用空间小于地址占用空间。
一次io读写,可以获取到 16K 大小的资源,我们称之为读取到的数据区域为 Page 。而我们的B树,B+树的索引结构,叶子节点上存放好多个关键字(索引值)和对应的数据,都会在一次IO操作中被 读取到缓存 中,所以在访问同一个页中的不同记录时,会在内存里操作,而不用再次进行IO操作了。除非发生了页的分裂,即要查询的行数据不在上次IO操作的缓存里,才会触发新的IO操作。
InnoDB与MyISAM对比:
使用聚簇索引的优势:
涉及到大数据量的排序、全表扫描、count之类的操作的话,还是MyISAM占优势些,因为索引所占空间小,这些操作是需要在内存中完成的。
简而言之: 聚簇索引第一次读就会把所有数据写进缓存(二层树只需要一次IO操作),非聚簇索引因为物理地址是乱的,每次都需要IO读取
聚簇索引需要注意的地方:
当使用主键为聚簇索引时,主键最好不要使用uuid,因为uuid的值太过离散,不适合排序且可能出线新增加记录的uuid,会插入在索引树中间的位置,导致索引树调整复杂度变大,消耗更多的时间和资源。
建议使用int类型的自增,方便排序并且默认会在索引树的末尾增加主键值,对索引树的结构影响最小。而且,主键值占用的存储空间越大,辅助索引中保存的主键值也会跟着变大,占用存储空间,也会影响到IO操作读取到的数据量。
为什么主键通常建议使用自增id
聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。如果主键不是自增id,那么它会不断地调整数据的物理地址、分页,当然也有其他一些措施来减少这些操作,但却无法彻底避免。但,如果是自增的,那就简单了,它只需要一 页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高。
什么时候下不能利用索引?
使用
like
进行查询的时候,如果匹配字符串的第一个字符为%
,就不能用索引查询语句使用复合索引的时候,没有使用最左边的索引字段
查询语句中只有
or
,且or
前后两个条件列都是索引的时候,可以使用索引;当or
前后有一个条件不是索引的时候,就不能使用索引