栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

MySQL 索引失效情况

MySQL 索引失效情况

MySQL 索引失效情况

防止索引失效的方式:

    索引全值匹配。最佳左前缀法则。不再索引上做任何操作(计算、函数、类型转换等),否则索引失效。存储引擎不能使用索引范围条件右侧的列。尽量使用覆盖索引。MySQL 在使用不等条件时,索引失效。is not null 无法使用索引。like 以通配符开头,MySQL 索引会失效;但以通配符结尾,索引不受影响。字符串不加单引号导致索引失效(类型转换)。使用 or ,索引失效。

SQL 索引失效分析:

注:其中有些索引的使用在数据量极小时可能会生效,但是一般不会有此情况

-- 按照用户表进行索引测试
create table user(
    uid int PRIMARY KEY,
		uname varchar(255) comment '用户名',
		level int(1) comment '等级',
		age int(2) comment '年龄',
		class int(1) comment '班级'
);

-- 插入数据
INSERT INTO USER VALUES(1015, "kafka",      1, 37, 3);
INSERT INTO USER VALUES(1014, "spring",     1, 37, 3);
INSERT INTO USER VALUES(1013, "redis",      1, 37, 3);
INSERT INTO USER VALUES(1012, "activemq",   1, 37, 3);
INSERT INTO USER VALUES(1011, "dubbo",      1, 37, 3);
INSERT INTO USER VALUES(1010, "rabbitmq",   1, 37, 3);
INSERT INTO USER VALUES(1001, "zhangsan",   1, 35, 3);
INSERT INTO USER VALUES(1002, "lisi",       1, 35, 1);
INSERT INTO USER VALUES(1003, "wangwu",     1, 32, 3);
INSERT INTO USER VALUES(1004, "songliu",    2, 28, 3);
INSERT INTO USER VALUES(1005, "sanqi",      2, 28, 1);
INSERT INTO USER VALUES(1006, "yujiangjun", 2, 25, 1);
INSERT INTO USER VALUES(1007, "ruofeng",    3, 25, 2);
INSERT INTO USER VALUES(1008, "kuake",      3, 23, 2);
INSERT INTO USER VALUES(1009, "xinyu",      3, 20, 2);
INSERT INTO USER VALUES(1016, "yangw",      2, 37, 3);
INSERT INTO USER VALUES(1017, "liuqi",      1, 37, 3);
INSERT INTO USER VALUES(1018, "susuo",      3, 37, 2);
INSERT INTO USER VALUES(1019, "deyik",      1, 37, 2);
INSERT INTO USER VALUES(1020, "makua",      2, 37, 2);

-- 创建索引
create index idx_lev_age_clazz on user(level, age, class);
create index idx_name_age on user(uname, age);

-- 最佳左前缀法则
EXPLAIN select uid, uname, level, age, class from user where level = 1 and age = 35 and class = 3;
EXPLAIN select uid, uname, level, age, class from user where level = 1 and age = 33;
EXPLAIN select uid, uname, level, age, class from user where class = 3 and level = 1 and age = 33;
EXPLAIN select uid, uname, level, age, class from user where uname = "xinyu" and age = 20;

--  where 阶段 破坏最佳左前缀法则 ** 覆盖索引可以抗住所有伤害,呜呜呜 **
EXPLAIN select uid, uname, level, age, class from user where age = 35 and class = 3;  -- 破坏最佳左前缀法则,无法走索引
EXPLAIN select uid, uname, level, age, class from user where level = 1 and class = 3; -- 无法走 level 后的索引,破坏最佳左前缀法则的连续性。
EXPLAIN select uid, uname, level, age, class from user where level > 1;  -- 不会走索引,采用了范围查询。
EXPLAIN select level, age, class from user where level > 1 and age = 25; -- 覆盖索引也不可以走!!! age 的索引没有走。
EXPLAIN select uid, uname, level, age, class from user where level = level + 1; -- 不会走索引,因为进行了计算操作。
EXPLAIN select uid, uname, level, age, class from user where uname like "%xinyu" and age = 20; -- 不会使用索引,使用了范围查询,且 % 打头,无法进行索引查询。
EXPLAIN select uid, uname, level, age, class from user where uname like "xinyu%" and age = 20; -- 可以走索引,因为 % 在末尾。
EXPLAIN select uid, uname, level, age, class from user where level = 1 and age != 35 and class = 3; -- 不走 不等式 后面的索引。
EXPLAIN select uid, uname, level, age, class from user where level is null and age = 35; -- is null 可以走索引
EXPLAIN select uid, uname, level, age, class from user where level is not null and age = 35; -- is not null 不可以走任何索引
EXPLAIN select uid, uname, level, age, class from user where uname = 20 and age = 20; -- 字符串类型不使用 引号,会发生类型转换,不会走索引。
EXPLAIN select uid, uname, level, age, class from user where level = 1 or age = 35 or class = 3; -- 使用 or 进行连接,不会使用索引。

EXPLAIN select uname, age from user where uname = 20 and age = 20; -- 覆盖索引可以走,类型转换型。
EXPLAIN select uname, age from user where uname like "%xinyu" and age = 20; -- 使用索引,覆盖索引,模糊搜索 % 在前。
EXPLAIN select level, age, class from user where level = level + 1; -- 覆盖索引可以,where 后进行了计算操作。
EXPLAIN select level, age, class from user where level is not null and age = 35; -- 覆盖索引可以运行,使用 is not null 情况。
EXPLAIN select level, age, class from user where level = 1 or age = 35 or class = 3; -- 覆盖索引可以运行,使用 or 连接符情况下。

-- order by 阶段 filesort 
EXPLAIN select uid, uname, level, age, class from user where level = 1 order by uname ; -- 出现了 filesort,因为没有使用索引字段。
EXPLAIN select uid, uname, level, age, class from user where age = 35 and class = 3 order by class; -- 虽然不会走索引,但也没出现 filesort,因为使用了 where 域的字段。
EXPLAIN select uid, uname, level, age, class from user where level = 1 and age = 33 order by class; -- 不会出现 firesort,使用了最佳左前缀法则。
EXPLAIN select uid, uname, level, age, class from user where level = 1 order by class ; -- 出现 filesort,破坏了最佳左前缀法则的连续性。
EXPLAIN select uid, uname, level, age, class from user where level = 1 order by uid ; -- 没有出现 filesort
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/752206.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号