索引可以提高查询的速度,但并不是使用带有索引的字段查询时,索引都会起作用。使用索引有几种特殊情况,在这些情况下,有可能使用带有索引的字段查询时,索引并没有起作用,下面重点介绍这几种特殊情况。

1. 查询语句中使用LIKE关键字

在查询语句中使用 LIKE 关键字进行查询时,如果匹配字符串的第一个字符为“%”,索引不会被使用。如果“%”不是在第一个位置,索引就会被使用。

例 1

为了便于理解,我们先查询 tb_student 表中的数据,SQL 语句和运行结果如下:

mysql> select * from tb_student_info;

+----+--------+--------+------+------+--------+------------+

| id | name   | deptId | age  | sex  | height | login_date |

+----+--------+--------+------+------+--------+------------+

|  1 | Dany   |      1 |   25 | F    |    160 | 2015-09-10 |

|  2 | Green  |      3 |   23 | F    |    158 | 2016-10-22 |

|  3 | Henry  |      2 |   23 | M    |    185 | 2015-05-31 |

|  4 | Jane   |      1 |   22 | F    |    162 | 2016-12-20 |

|  5 | Jim    |      1 |   66 | M    |    175 | 2016-01-15 |

|  6 | John   |      2 |   21 | M    |    172 | 2015-11-11 |

|  7 | Lily   |      6 |   22 | F    |    165 | 2016-02-26 |

|  8 | Susan  |      4 |   23 | F    |    170 | 2015-10-01 |

|  9 | Thomas |      3 |   22 | M    |    178 | 2016-06-07 |

| 10 | Tom    |      4 |   23 | M    |    165 | 2016-08-05 |

| 12 | jijiji |      1 |  667 | 1    |    176 | 2020-08-24 |

+----+--------+--------+------+------+--------+------------+

11 rows in set (0.00 sec)

下面在查询语句中使用 LIKE 关键字,且匹配的字符串中含有“%”符号,使用 EXPLAIN 分析查询情况,SQL 语句和运行结果如下:

mysql> explain select * from tb_student_info where name like '%y';+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

| 1 | SIMPLE | tb_student_info | NULL | ALL | NULL | NULL | NULL | NULL | 12 | 11.11 | Using where |

+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

1 row in set, 1 warning (0.00sec)

mysql> alter table tb_student_info add indexindex_name (name);

Query OK,0 rows affected (0.51sec)

Records:0 Duplicates: 0 Warnings: 0mysql> explain select * from tb_student_info where name like '%y';+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

| 1 | SIMPLE | tb_student_info | NULL | ALL | NULL | NULL | NULL | NULL | 12 | 11.11 | Using where |

+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

1 row in set, 1 warning (0.00sec)

mysql> explain select * from tb_student_info where name like 'y%';+----+-------------+-----------------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+

| 1 | SIMPLE | tb_student_info | NULL | range | index_name | index_name | 77 | NULL | 1 | 100.00 | Using index condition |

+----+-------------+-----------------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+

1 row in set, 1 warning (0.07 sec)

第一个查询语句执行后,rows 参数的值为 12,表示这次查询过程中查询了 12 条记录;创建索引之后第二个查询语句执行后,rows 参数的值为 12,表示这次查询过程只查询 12 条记录。第三次查询同样是使用 name 字段进行查询,因为第一个和第二个查询语句的 LIKE 关键字后的字符串是以“%”开头的,所以第二个查询语句没有使用索引(第一个查询的时候还没建立索引),而第三个查询语句使用了索引 index_name。

注意: 关于explain的使用, 可以查看这里

2. 查询语句中使用多列索引

多列索引是在表的多个字段上创建一个索引,只有查询条件中使用了这些字段中的第一个字段,索引才会被使用。

例 2

在 name 和 age 两个字段上创建多列索引,并验证多列索引的使用情况,SQL 语句和运行结果如下:

mysql> alter table tb_student_info add indexindex_name_age (name, age);

Query OK,0 rows affected (0.56sec)

Records:0 Duplicates: 0 Warnings: 0

删除之前name列上的索引'index_name'

mysql> drop index index_name ontb_student_info;

Query OK,0 rows affected (0.25sec)

Records:0 Duplicates: 0 Warnings: 0

查看现在表tb_student_info上的索引

mysql> show index fromtb_student_info\G;*************************** 1. row ***************************

Table: tb_student_info

Non_unique:0Key_name:PRIMARYSeq_in_index:1Column_name: id

Collation: A

Cardinality:13Sub_part:NULLPacked:NULL

Null:

Index_type: BTREE

Comment:

Index_comment:

Visible: YES

Expression:NULL

*************************** 2. row ***************************

Table: tb_student_info

Non_unique:1Key_name: index_name_age

Seq_in_index:1Column_name: name

Collation: A

Cardinality:11Sub_part:NULLPacked:NULL

Null:

Index_type: BTREE

Comment:

Index_comment:

Visible: YES

Expression:NULL

*************************** 3. row ***************************

Table: tb_student_info

Non_unique:1Key_name: index_name_age

Seq_in_index:2Column_name: age

Collation: A

Cardinality:11Sub_part:NULLPacked:NULL

Null: YES

Index_type: BTREE

Comment:

Index_comment:

Visible: YES

Expression:NULL

3 rows in set (0.00 sec)

如上, 一个主键, 还有一个是组合索引, 组合字段是name和age...

执行分别查询name和age的sql, 如下:

mysql> explain select * from tb_student_info where name like 'y%';+----+-------------+-----------------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+

| 1 | SIMPLE | tb_student_info | NULL | range | index_name_age | index_name_age | 77 | NULL | 1 | 100.00 | Using index condition |

+----+-------------+-----------------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+

1 row in set, 1 warning (0.00sec)

mysql> explain select * from tb_student_info where age = 12;+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

| 1 | SIMPLE | tb_student_info | NULL | ALL | NULL | NULL | NULL | NULL | 12 | 10.00 | Using where |

+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+

1 row in set, 1 warning (0.00 sec)

第一条查询语句的查询条件使用了 name 字段,分析结果显示 rows 参数的值为 1,且查询过程中使用了 index_name_age 索引。第二条查询语句的查询条件使用了 age 字段,结果显示 rows 参数的值为 12,且 key 参数的值为 NULL,这说明第二个查询语句没有使用索引。

因为 name 字段是多列索引的第一个字段,所以只有查询条件中使用了 name 字段才会使 index_name_age 索引起作用。

mysql> explain select * from tb_student_info where age=23 and name = 'Green';+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------------+------+----------+-------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------------+------+----------+-------+

| 1 | SIMPLE | tb_student_info | NULL | ref | index_name_age | index_name_age | 82 | const,const | 1 | 100.00 | NULL |

+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------------+------+----------+-------+

1 row in set, 1 warning (0.00sec)

mysql> explain select * from tb_student_info where name = 'Green' and age = 23;+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------------+------+----------+-------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------------+------+----------+-------+

| 1 | SIMPLE | tb_student_info | NULL | ref | index_name_age | index_name_age | 82 | const,const | 1 | 100.00 | NULL |

+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------------+------+----------+-------+

1 row in set, 1 warning (0.00 sec)

如上, 查询中的where条件中用到了name和age两列, 可以看出, 不管where条件中先写age还是name都对使用索引index_name_age没有影响, 因为两个sql中的where条件中都有name列, 根据索引index_name_age的第一个字段就是name, 所以索引被使用

mysql> explain select * from tb_student_info where name = 'Green' and sex = 'F';+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------+------+----------+-------------+

| 1 | SIMPLE | tb_student_info | NULL | ref | index_name_age | index_name_age | 77 | const | 1 | 10.00 | Using where |

+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------+------+----------+-------------+

1 row in set, 1 warning (0.00 sec)

where条件中使用了name和sex, 依然使用了索引, 因为where条件中的name得以使用索引...

3. 查询语句中使用OR关键字

查询语句只有 OR 关键字时,如果 OR 前后的两个条件的列都是索引,那么查询中将使用索引。如果 OR 前后有一个条件的列不是索引,那么查询中将不使用索引。

例 3

下面演示 OR 关键字的使用。

mysql> explain select * from tb_student_info where name='Green' or age>1;+----+-------------+-----------------+------------+------+----------------+------+---------+------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+------+----------------+------+---------+------+------+----------+-------------+

| 1 | SIMPLE | tb_student_info | NULL | ALL | index_name_age | NULL | NULL | NULL | 12 | 40.00 | Using where |

+----+-------------+-----------------+------------+------+----------------+------+---------+------+------+----------+-------------+

1 row in set, 1 warning (0.00sec)

mysql> explain select * from tb_student_info where name='Green' or (name='Green' and age=23);+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------+------+----------+-------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------+------+----------+-------+

| 1 | SIMPLE | tb_student_info | NULL | ref | index_name_age | index_name_age | 77 | const | 1 | 100.00 | NULL |

+----+-------------+-----------------+------------+------+----------------+----------------+---------+-------+------+----------+-------+

1 row in set, 1 warning (0.00sec)

mysql> explain select * from tb_student_info where name='Green' or id=1;+----+-------------+-----------------+------------+-------------+------------------------+------------------------+---------+------+------+----------+-------------------------------------------------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered |Extra|

+----+-------------+-----------------+------------+-------------+------------------------+------------------------+---------+------+------+----------+-------------------------------------------------------+

| 1 | SIMPLE | tb_student_info | NULL | index_merge | PRIMARY,index_name_age | index_name_age,PRIMARY | 77,4 | NULL | 2 | 100.00 | Using sort_union(index_name_age,PRIMARY); Using where |

+----+-------------+-----------------+------------+-------------+------------------------+------------------------+---------+------+------+----------+-------------------------------------------------------+

1 row in set, 1 warning (0.00 sec)

由于 单独的age字段没有索引,所以第一条查询语句没有使用索引, 因为or后面的age单独使用, 没有涉及到索引index_name_age第一个字段name的使用;第二个查询or前面的name和or后面的都设计到了索引index_name_age, 所以使用了此索引; 而最后一个查询name 字段和 id 字段都有索引, 使用了 index_name_age 和 PRIMARY 索引

其实综上一定要记住, 组合索引的使用, 一定要遵循最左匹配原则!

总结

使用索引查询记录时,一定要注意索引的使用情况。例如,LIKE 关键字配置的字符串不能以“%”开头;使用多列索引时,查询条件必须要使用这个索引的第一个字段;使用 OR 关键字时,OR 关键字连接的所有条件都必须使用索引。

mysql 有索引 不被使用方法_MySQL教程100-索引在什么情况下不会被使用?相关推荐

  1. 利用mysql上传木马_通过Mysql语句生成后门木马的方法_MySQL

    通过Mysql 的语句生成后门木马的方法! SELECT * FROM `vbb_strikes` WHERE 1 union select 2,3,0x3C3F7068702073797374656 ...

  2. mysql上传木马_通过Mysql语句生成后门木马的方法_MySQL

    通过Mysql 的语句生成后门木马的方法! SELECT * FROM `vbb_strikes` WHERE 1 union select 2,3,0x3C3F7068702073797374656 ...

  3. 启动mysql55命令_mysql服务的启动和停止登陆mysql增加新用命令和方法实例教程

    mysql服务的启动和停止登陆mysql增加新用命令和方法实例教程,mysql常见常用操作命令汇总总结,增删查改命令,启动用户管理,数据库管理等. mysql服务的启动和停止 net stop mys ...

  4. mysql 8.0.18安装,mysql 8.0.18 安装配置方法图文教程

    mysql 8.0.18 安装配置方法图文教程 本文记录了mysql 8.0.18 安装配置图文教程,供大家参考,具体内容如下 第一步:下载MySql 下载地址:MySQL 第二步:安装MySql 打 ...

  5. 最全的mysql 5.7.13_最全的mysql 5.7.13 安装配置方法图文教程(linux) 强烈推荐!

    linux环境Mysql 5.7.13安装教程分享给大家,供大家参考,具体内容如下 1系统约定 安装文件下载目录:/data/software Mysql目录安装位置:/usr/local/mysql ...

  6. mysql 5.6.15安装图解_Windows8下mysql 5.6.15 安装配置方法图文教程

    MySQL是一款我十分喜欢的数据库,今天在Windows8系统下,下载了MySQL进行安装配置,下载地址:点击打开链接 特在此记录下自己的过程,一是起到总结的作用,二是能帮助那些和我一样在安装配置中有 ...

  7. 转载:mysql 5.7.10 安装配置方法图文教程——来自脚本之家网,作者是汤高

    mysql 5.7.10 安装配置方法图文教程 作者:汤高 字体:[增加 减小] 类型:转载 时间:2016-06-22 我要评论 这篇文章主要为大家分享了mysql 5.7.10 安装配置方法图文教 ...

  8. ubuntu18.4中查看mysql_Ubuntu18.0.4下mysql 8.0.20 安装配置方法图文教程

    mysql 8.0.20 安装配置方法图文教程整理下,供大家参考. 一.准备工作 1.检查是否已经安装mysql 当前计算机没有安装mysql. 2.下载MySQL8.0. 根据MySQL安装指南,发 ...

  9. mysql索引教程_MySQL教程96-MySQL索引类型

    索引的类型和存储引擎有关,每种存储引擎所支持的索引类型不一定完全相同.MySQL 索引可以从存储方式.逻辑角度和实际使用的角度来进行分类. 存储方式区分 根据存储方式的不同,MySQL 中常用的索引在 ...

最新文章

  1. [Nginx] Nginx 配置location总结
  2. MongoDB Windows环境安装及配置
  3. 实现SELECT的全选,反选,AB选的JAVASCRIPT代码
  4. golang学习笔记01
  5. linux mysql 磁盘空间_磁盘空间满了之后MySQL会怎样
  6. heap c语言数组实现,垃圾回收算法实现之 - 分代回收(完整可运行C语言代码)...
  7. 台式电脑键盘字母乱了_电脑键盘的详细介绍,想懂点电脑必看
  8. mysql 5.6 64位解压版_MySQL 5.6 for Windows 解压缩版配置安装(win 10 64位亲测)附安装包下载链接...
  9. tar.xz文件怎样解压
  10. C#使用webclient下载图片返回403forbiden
  11. 印尼Widya Robotics携手华为云,让建筑工地安全看得见
  12. SDL游戏之路(十一)--按钮制作
  13. 门外汉掌握数据分析处理技术的路线图
  14. 在线正则表达式测试工具
  15. 科研用matlab还是python_科的解释|科的意思|汉典“科”字的基本解释
  16. 能力值的计算:一年 365 天,以第 1 天的能力值为基数,记为 1.0,当每天好好学习时能力值相比前一天提高 1‰,当没有学习时由于遗忘等原因能力值相比前一天下降 1‰
  17. 软件工程第二次作业(王伟东)
  18. Prompt-Tuning——深度解读一种新的微调范式
  19. java架构师和大数据架构师有哪些不同
  20. 《每秒处理10万订单乐视集团支付架构》学有所得

热门文章

  1. 【Java】while和do-while循环比较测试案例
  2. 【Markdown】新手快速入门基础教程
  3. Visual Studio 2017版本15.9现在可用
  4. node和npm是什么_什么是npm? 面向初学者的Node Package Manager教程
  5. 跳转点算法_跳转搜索算法介绍
  6. git规则写法_3条简单的规则将帮助您成为Git大师
  7. gatsby_与Gatsby一起使用React Context API
  8. 尚学堂java 参考答案 第七章
  9. 0宽字符加密_一文看懂异或加密,有动画演示呦
  10. win7下安装linux(CentOS)过程中遇到的问题总结