优点
- 索引大大减小了服务器需要扫描的数据量
- 索引可以帮助服务器避免排序和临时表
- 索引可以将随机IO变成顺序IO
- 索引对于InnoDB(对索引支持行级锁)非常重要,因为它可以让查询锁更少的元组。在MySQL5.1和更新的版本中,InnoDB可以在服务器端过滤掉行后就释放锁,但在早期的MySQL版本中,InnoDB直到事务提交时才会解锁。对不需要的元组的加锁,会增加锁的开销,降低并发性。 InnoDB仅对需要访问的元组加锁,而索引能够减少InnoDB访问的元组数。但是只有在存储引擎层过滤掉那些不需要的数据才能达到这种目的。一旦索引不允许InnoDB那样做(即索引达不到过滤的目的),MySQL服务器只能对InnoDB返回的数据进行WHERE操作,此时,已经无法避免对那些元组加锁了。如果查询不能使用索引,MySQL会进行全表扫描,并锁住每一个元组,不管是否真正需要。
- 关于InnoDB、索引和锁:InnoDB在二级索引上使用共享锁(读锁),但访问主键索引需要排他锁(写锁)
缺点
- 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存索引文件。
- 建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。
- 如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。
- 对于非常小的表,大部分情况下简单的全表扫描更高效;
索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
因此应该只为最经常查询和最经常排序的数据列建立索引。
MySQL里同一个数据表里的索引总数限制为16个。
索引的分类
在一个表中,主键索引只能有一个,唯一索引可以有多个。
- 主键索引(PRIMARY KEY)
-
唯一的标识,主键不可重复,只能有一个列作为主键
-
- 唯一索引(UNIQUE KEY)
-
避免重读的列出现,唯一索引可以重复,多个列都可以标识为唯一索引
-
- 常规索引(KEY / INDEX)
-
默认的,通过index或key关键字来设置
-
- 全文索引(FULLTEXT)
-
在特定的数据库引擎下采用,之前只有MYISAM有
-
快速定位数据
-
基础语法
-- 索引的使用 -- 方式1:在创建表的时候给字段增加索引 -- 方式2:表创建完毕后,增加索引 -- 显示所有的索引信息 SHOW INDEX FROM `student` -- 增加一个全文索引:格式:索引类型 索引名(列名),主键索引只要有索引名就行了 ALTER TABLE `school`.`student` ADD FULLTEXT INDEX `StudentName`(`StudentName`) -- 删除索引 DROP INDEX 索引名 ON 表名 -- EXPLAIN分析sql执行的情况 EXPLAIN SELECT * FROM `student`; -- 非全文索引 EXPLAIN SELECT * FROM `student` WHERE MATCH(`StudentName`) AGAINST('郭') -- 通过全文索引进行查找
创建表结构
CREATE TABLE `demo`.`users`(
`u_id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`name` VARCHAR(50) NOT NULL DEFAULT '用户昵称' COMMENT '用户昵称',
`email` VARCHAR(50) NOT NULL COMMENT '用户邮箱',
`phone` VARCHAR(20) NOT NULL COMMENT '电话号码',
`sex` TINYINT(4) DEFAULT 0 COMMENT '0男1女',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`age` TINYINT(4) DEFAULT 0 COMMENT '年龄',
`create_time` DATETIME COMMENT '创建时间',
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`u_id`)
);
创建函数添加模拟数据
DELIMITER $$
CREATE
FUNCTION `demo`.`mock_data`()
RETURNS INT
BEGIN
-- 创建变量为i
DECLARE i INT(11) DEFAULT 1;
WHILE i < 1000000 DO
-- 获取当前系统时间
SELECT CURRENT_TIMESTAMP INTO @time;
-- 插入语句
-- CONCAT(a,b) 把a和b两个字符串拼接
-- RAND() 随机数
-- FLOOR() 向下取整
-- UUID() 唯一ID
INSERT INTO `users`(`name`,`email`,`phone`,`sex`,`password`,`age`,`create_time`,`update_time`)
VALUE(
CONCAT('用户',i),
CONCAT(FLOOR((RAND()*9999)),i,'@qq.com'),
CONCAT('13',FLOOR(RAND()*999999999)),
FLOOR(RAND()*2),
UUID(),
FLOOR(RAND()*100),
@time,
@time
);
SET i = i + 1;
END WHILE;
RETURN i;
END$$
DELIMITER ;
执行函数
SELECT `mock_data`();
执行语句查看耗时
SELECT * FROM `users` WHERE NAME = "用户99999";
创建索引
CREATE INDEX 索引名 ON 表(字段) 索引名起名规范 id_表名_字段名
CREATE INDEX id_users_name ON `users`(`name`);
再次执行语句查看耗时
SELECT * FROM `users` WHERE `phone` = "1330039060";
最后修改于 2021-09-30 09:12:47
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

