索引失效案例

  • 1.全值匹配我最爱,最左前缀要遵守。
  • 2.带头大哥不能死,中间兄弟不能段。
  • 3.索引列上少计算,范围之后全失效。
  • 4.like 百分写最右,覆盖索引不写*。
  • 5.不等空值还有or,索引失效要少用。
  • 6.字符串引号不可丢,SQL高级也不难。

全值匹配我最爱

全职匹配我最爱指的是,查询的字段按照顺序在索引中都可以匹配到

最佳左前缀法则

使用复合索引,需要遵循最佳左前缀法则,即如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。

主键插入顺序 

 

如果此时再插入一条主键值为 9 的记录,那它插入的位置就如下图:  

可这个数据页已经满了,再插进来咋办呢?我们需要把当前 页面分裂 成两个页面,把本页中的一些记录 移动到新创建的这个页中。页面分裂和记录移位意味着什么?意味着: 性能损耗 !所以如果我们想尽量 避免这样无谓的性能损耗,最好让插入的记录的 主键值依次递增 ,这样就不会发生这样的性能损耗了。 所以我们建议:让主键具有 AUTO_INCREMENT ,让存储引擎自己为表生成主键,而不是我们手动插入 , 比如: person_info 表: 

CREATE TABLE person_info(
   id INT UNSIGNED NOT NULL AUTO_INCREMENT,
   name VARCHAR(100) NOT NULL,
   birthday DATE NOT NULL,
   phone_number CHAR(11) NOT NULL,
   country varchar(100) NOT NULL,
    PRIMARY KEY (id),
    KEY idx_name_birthday_phone_number (name(10), birthday, phone_number)
);  

我们自定义的主键列 id 拥有 AUTO_INCREMENT 属性,在插入记录时存储引擎会自动为我们填入自增的 主键值。这样的主键占用空间小,顺序写入,减少页分裂。  

计算、函数、类型转换(自动或手动)导致索引失效

创建索引

CREATE INDEX idx_name ON student(NAME);

 索引优化生效

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.name LIKE 'abc%';

索引优化失效 

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE LEFT(student.name,3) = 'abc';

类型转换导致索引失效 

下列哪个sql语句可以用到索引。(假设name字段上设置有索引)

# 未使用到索引

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE name=123; 
# 使用到索引

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE name='123'

name=123发生类型转换,索引失效。 

范围条件右边的列索引失效 

ALTER TABLE student DROP INDEX idx_name;

ALTER TABLE student DROP INDEX idx_age;

ALTER TABLE student DROP INDEX idx_age_classid;

EXPLAIN SELECT SQL_NO_CACHE * FROM student 

WHERE student.age=30 AND student.classId>20 AND student.name = 'abc' 

 

create index idx_age_name_classid on student(age,name,classid);  

将范围查询条件放置语句最后: 

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.age=30 AND student.name = 

'abc' AND student.classId>20 ;

 

不等于(!= 或者<>)索引失效 

is null可以使用索引,is not null无法使用索引

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age IS NULL; 
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age IS NOT NULL;

like以通配符%开头索引失效 

拓展:Alibaba《Java开发手册》

【强制】页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。

 

OR 前后存在非索引的列,索引失效 

# 未使用到索引

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age = 10 OR classid = 100;
#使用到索引

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age = 10 OR name = 'Abel';

 数据库和表的字符集统一使用utf8mb4

统一使用utf8mb4( 5.5.3版本以上支持)兼容性更好,统一字符集可以避免由于字符集转换产生的乱码。不 同的 字符集 进行比较前需要进行 转换 会造成索引失效。

  • 25
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
MySQL匹配原则失效的场景包括: 1. 如果在查询条件中使用了函数或者表达式,则可能导致最匹配失效。例如,查询语句中使用了函数或者表达式,如`SELECT * FROM users WHERE age + 10 = 35 AND name = 'John'`,这种情况下MySQL无法使用索引,因为它无法对函数或者表达式进行索引。 2. 如果在查询条件中使用了OR操作符,则可能导致最匹配失效。例如,查询语句中使用了OR操作符,如`SELECT * FROM users WHERE name = 'John' OR age = 25`,这种情况下MySQL也无法使用索引,因为它无法同时对两个列进行索引。 3. 如果在查询条件中使用了不等于号(<>),则可能导致最匹配失效。例如,查询语句中使用了不等于号,如`SELECT * FROM users WHERE name <> 'John' AND age = 25`,这种情况下MySQL也无法使用索引,因为它无法对不等于号进行索引。 4. 如果在查询条件中使用了LIKE操作符,并且通配符出现在边,则可能导致最匹配失效。例如,查询语句中使用了LIKE操作符,如`SELECT * FROM users WHERE name LIKE '%John' AND age = 25`,这种情况下MySQL也无法使用索引,因为它无法对边的通配符进行索引。 一个不走索引案例是,假设我们有一个名为users的表,其中包含id、name和age三列。如果我们在使用查询语句时,使用了以下条件: ``` SELECT * FROM users WHERE name='John' AND age>25; ``` 如果我们在表中创建了一个包含name和age两列的联合索引,则MySQL会使用该联合索引进行匹配。但是,由于age列上使用了大于号,所以MySQL无法使用该索引,因为索引只能用于等于和小于操作。因此,MySQL不得不扫描整个表来查找匹配的行,这会导致查询性能变差。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个风轻云淡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值