-
索引的作用是什么
告诉存储引擎如何快速的查找所需要的数据,类似目录,可以快速定位到某个区域,而如果没有索引,只能一页一页翻找寻找需要的内容。在磁盘上表现就是要慢慢扫描查找。 -
Innodb支持的索引类型
Btree索引
自适应HASH索引
全文索引
空间索引
一般没特别说明,都是指Btree索引,结构如下图
-- 查询出2019年1月1号之后注册的男性会员昵称
EXPLAIN
SELECT user_nick
FROM imc_user
WHERE sex=1 AND reg_time>'2019-01-01';
输出
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
------ ----------- -------- ---------- ------ ------------- ------ ------- ------ ------ -------- -------------
1 SIMPLE imc_user (NULL) ALL idx_sex (NULL) (NULL) (NULL) 2530 3.33 Using where
-- 筛选性
SELECT COUNT(DISTINCT sex)
,COUNT(DISTINCT DATE_FORMAT(reg_time,'%Y-%m-%d'))
,COUNT(*)
,COUNT(DISTINCT sex)/COUNT(*)
,COUNT(DISTINCT DATE_FORMAT(reg_time,'%Y-%m-%d'))/COUNT(*)
FROM imc_user
CREATE INDEX idx_regtime ON imc_user(reg_time)
EXPLAIN
SELECT user_nick
FROM imc_user
WHERE sex=1 AND reg_time>'2019-01-01';
'再次获取sql的执行计划,输出'
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
------ ----------- -------- ---------- ------ ------------------- ----------- ------- ------ ------ -------- ------------------------------------
1 SIMPLE imc_user (NULL) range idx_sex,idx_regtime idx_regtime 5 (NULL) 516 10.00 Using index condition; Using where
'添加索引之后,再次执行执行计划,要比之前没索引的情况好 '
DROP INDEX idx_regtime ON imc_user
-- 给sex添加索引后,并不会使用到索引,同样要扫描2530行数据
-- 说明在筛选性不好的列上建立索引,没有任何作用
CREATE INDEX idx_sex ON imc_user(sex)
DROP INDEX idx_sex ON imc_user
区分度最高的列放在联合索引最左侧,因为mysql从左侧开始匹配,左侧区分越高,能筛选的越高,另外索引键值长度越小,性能也越好
如果用abc组成的索引,查询ac,那只能用到a的索引
好的索引能提高数据库性能,不好的索引也能降低数据库性能
一方面索引能增加查询效率,但同样会降低插入和更新数据的速率,甚至在某些情况索引同样会降低查询效率,因为mysql优化器在选择如何优化查询时,会根据统一信息对可以用到的索引进行评估,以生成最优执行计划,如果有太多索引都能用于查询,会增加mysql优化器生成执行计划的时间
MySQL数据页大小为16K,每行记录越长,每个数据页存储的记录数就越少,因此在对数据进行检索时,会产生更多的IO,所以索引的长度大小也会影响检索速度,索引长度越小越好
使用 or 运算符来关联多个查询条件,可能无法用到索引,但in列表查询不一样,是可以用到索引的,所以在优化sql时,有一种方法就是用in代替or,但如果in()表中数据太多,mysql优化器认为效率不好也可能用全局扫描的方法
mysql优化器会自动调整过滤查询的顺序,以适应索引键值的顺序 ,从而正确的使用索引
EXPLAIN
SELECT course_id,b.class_name,d.type_name,c.level_name,title,score
FROM imc_course a
JOIN imc_class b ON b.`class_id`=a.`class_id`
JOIN imc_level c ON c.`level_id`=a.`level_id`
JOIN imc_type d ON d.`type_id`=a.`type_id`
WHERE c.`level_name`='高级'
AND b.`class_name`='MySQL'
-- 联合索引,按照可筛选性排序
CREATE INDEX idx_classid_typeid_levelid ON imc_course(class_id,type_id,level_id);
DROP INDEX idx_classid_typeid_levelid ON imc_course;
CREATE INDEX idx_levelname ON imc_level(level_name)
-- 查询出不存在课程的分类名称
EXPLAIN
SELECT class_name
FROM imc_class
WHERE class_id NOT IN (SELECT class_id FROM imc_course )
来源:https://blog.csdn.net/weixin_43456598/article/details/100541167