本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动连接sql
针对索引失效场景,便于优化SQL查询markdown
基于如下表结构验证索引失效场景app
CREATE TABLE `dynamic_info` (
`id` int(32) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL COMMENT '工做动态标题',
`content` text COMMENT '工做动态内容',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立时间',
`creator` varchar(64) DEFAULT NULL COMMENT '建立人',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
`docid` text COMMENT '爱数文件id',
`version_num` int(11) DEFAULT NULL COMMENT '版本号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='工做动态';
复制代码
添加组合索引、全文索引函数
alter table dynamic_info
add index
idx_dynamic_titleCreatorVersionNum(title,creator,version_num);
alter table dynamic_info
add FULLTEXT
idx_dynamic_content(content);
复制代码
EXPLAIN select * from dynamic_info where title = '通知' and creator = '5' and version_num = 1;
复制代码
从执行计划可知索引总长度为1287post
EXPLAIN select * from dynamic_info where title = '通知';
复制代码
EXPLAIN select * from dynamic_info where title = '通知' and creator = '5';
复制代码
4.使用组合索引第一三个字段做为查询条件,索引有效性能
EXPLAIN select * from dynamic_info where title = '通知' and version_num = 2;
复制代码
1.使用组合索引第二三个字段做为查询条件,索引失效优化
EXPLAIN select * from dynamic_info where creator = '5' and version_num = 1;
复制代码
EXPLAIN select * from dynamic_info where LEFT(title,1) = '通';
复制代码
使用left(str,length)函数函数对字符串截取,致使索引失效ui
EXPLAIN select * from dynamic_info where title = '通知' and creator = '5';
EXPLAIN select * from dynamic_info where title = '通知' and creator > '5' and version_num = 2;
复制代码
结合以前的key_len分析,索引用到一个、二个、三个字段时,key_len分别对应102三、128二、1287,此处的查询只用到title和creator字段,因为creator是个范围查询,致使索引version_num字段上索引失效url
EXPLAIN select title,creator,version_num from dynamic_info where title = '通知' and version_num = 1 and creator = '5';
EXPLAIN select * from dynamic_info where title = '通知' and creator = '5' and version_num = 1 ;
复制代码
select title,creator,version_num 用到覆盖索引,索引类型为ref,性能好于range,此外Extra显示用到Using index,表名只须要从索引树中寻找数据,不需在表中查找,而select * 可能须要查询非索引其余字段,Extra显示用到Using where,代表须要到表中查找。因此select * 比select 索引字段 性能要低spa
EXPLAIN select * from dynamic_info where title = 20210520;
复制代码
MySQL执行一条SQL语句先会优化SQL,将数字转换成String来查询,致使索引失效 解决索引失效方法:字段类型为varchar,查询的值为数字,须要添加单引号,索引才有效
EXPLAIN select * from dynamic_info where title != '通知';
EXPLAIN select * from dynamic_info where title <> '通知';
复制代码
7. 查询条件使用is null,is not null,索引失效
EXPLAIN select * from dynamic_info where content is null;
EXPLAIN select * from dynamic_info where content is not null;
复制代码
8. 使用like以通配符开头(%?%),索引失效
EXPLAIN select * from dynamic_info where content like '%通知';
EXPLAIN select * from dynamic_info where content like '%通知%';
EXPLAIN select * from dynamic_info where content like '通知%';
复制代码
针对已有组合索引,查询使用like以通配符开头的SQL,可以使用覆盖索引,即select的字段所有都被创建了索引
EXPLAIN select title,creator,version_num from dynamic_info where title like '%通知%';
复制代码
9. 使用or链接条件,索引失效
EXPLAIN select content from dynamic_info where content = '通知' or content = '5';
复制代码