索引失效案例

简介: 索引失效案例

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

全值匹配我最爱

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

最佳左前缀法则

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

主键插入顺序

9dc80697bb6b49ac9ab76d0e4f73d85f.png

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


image.png

可这个数据页已经满了,再插进来咋办呢?我们需要把当前 页面分裂 成两个页面,把本页中的一些记录 移动到新创建的这个页中。页面分裂和记录移位意味着什么?意味着: 性能损耗 !所以如果我们想尽量 避免这样无谓的性能损耗,最好让插入的记录的 主键值依次递增 ,这样就不会发生这样的性能损耗了。 所以我们建议:让主键具有 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' 

1653320c71054123977034b43523a5b4.png

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 ;

04c9cbc556a44667a154aeb4dc6306ad.png


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

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以通配符%开头索引失效

7d382126546f4e0bad0e0197da6e02ef.png

拓展: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版本以上支持)兼容性更好,统一字符集可以避免由于字符集转换产生的乱码。不 同的 字符集 进行比较前需要进行 转换 会造成索引失效。

相关文章
|
7月前
|
SQL Oracle 关系型数据库
分析索引失效的几种情况
联合索引 is not null 只要在建立的索引列(不分先后)都会走, in null时 必须要和建立索引第一列一起使用,当建立索引第一位置条件是is null 时,其他建立索引的列可以是is null(但必须在所有列 都满足is null的时候),或者=一个值; 当建立索引的第一位置是=一个值时,其他索引列可以是任何情况(包括is null =一个值),以上两种情况索引都会走。其他情况不会走。
103 1
|
7月前
|
SQL Oracle 关系型数据库
索引失效的情况分析
大家都知道,一条查询语句走了索引和没走索引的查询效率是非常大的,在我们建好了表,建好了索引后,但是一些不好的sql会导致我们的索引失效,下面介绍一下索引失效的几种情况
47 0
|
7月前
|
SQL 关系型数据库 MySQL
14. 什么情况下索引会失效 ?
了解 MySQL 索引失效的情况对优化 SQL 查询至关重要。避免在列上使用函数、运算、!=、not in、OR 和 %value% LIKE 操作,以保持索引有效性。使用组合索引代替多个单列索引,防止范围查询后的列无法使用索引。注意,NULL 值、列类型不匹配和隐式转换也可能导致索引失效。
99 0
|
7月前
|
SQL 关系型数据库 MySQL
索引失效的10中场景
索引失效的10中场景
|
SQL 存储 大数据
案例12-数据类型不一致导致索引失效
数据类型不一致导致索引失效
183 0
|
存储 SQL Oracle
Oracle优化避免索引失效
Oracle优化避免索引失效
374 0
|
SQL 关系型数据库 MySQL
MySQL数据库索引失效的10种场景
MySQL数据库索引失效的10种场景
417 0
|
存储 关系型数据库 MySQL
教你优雅的实现索引失效
教你优雅的实现索引失效
92 0
|
关系型数据库 MySQL 索引
索引失效的情况
索引失效的情况
83 0
|
数据库 索引
MysSQL索引会失效的几种情况分析
MysSQL索引会失效的几种情况分析
154 0
MysSQL索引会失效的几种情况分析