MySQL导致索引失效的几种情况

yizhihongxing

MySQL导致索引失效的几种情况

在使用MySQL数据库时,我们经常需要利用索引提高查询效率,但是有时候我们发现索引并没有起到预期的作用,这可能是索引被失效了,下面列举了几种常见的MySQL导致索引失效的情况:

  1. 对索引列进行函数操作

如果查询条件中对索引列进行了函数操作,那么MySQL就无法使用这个索引了。

例如下面的查询语句:

SELECT * FROM table WHERE YEAR(create_time) = 2021;

如果create_time上有索引,那么这个索引将无法被使用,因为YEAR(create_time)的操作将会导致索引失效,此时可以考虑将2021也转为日期类型与create_time比较,或者将YEAR(create_time)的结果计算好后作为查询参数传递。

  1. 在联合索引中未按照顺序使用

如果一个表上有多个索引,我们可以考虑使用联合索引提高查询效率。但是,如果我们在联合索引中未按照顺序使用,则索引也会失效。

例如下面的查询语句:

SELECT * FROM table WHERE name = 'John' AND age > 18;

如果表上有一个联合索引(name, age),那么这个索引将无法被使用,因为查询时未按照索引中列的顺序使用。此时可以考虑创建一个(age, name)的索引,或者将查询改为WHERE age > 18 AND name = 'John'。

示例说明:

首先,我们建立一个名为student的表,其结构如下:

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `age` int(11) NOT NULL,
  `create_time` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

接下来,我们向表中插入50000条模拟数据:

SET autocommit=0;
START TRANSACTION;
INSERT INTO student (name, age, create_time) VALUES
('Alex',20,'2021-01-01'),('Bob',23,'2021-01-02'),('Carl',26,'2021-01-03'),
('David',29,'2021-01-04'),('Eric',32,'2021-01-05'),('Frank',35,'2021-01-06'),
('Grace',38,'2021-01-07'),('Helen',41,'2021-01-08'),('Ivy',44,'2021-01-09'),
('Jack',47,'2021-01-10'),('Kelly',50,'2021-01-11'),('Lily',53,'2021-01-12'),
('Mike',56,'2021-01-13'),('Nancy',59,'2021-01-14'),('Oliver',62,'2021-01-15'),
('Paul',65,'2021-01-16'),('Queen',68,'2021-01-17'),('Robert',71,'2021-01-18'),
('Sam',74,'2021-01-19'),('Tracy',77,'2021-01-20'),('Ubaid',80,'2021-01-21'),
('Vivian',83,'2021-01-22'),('Wendy',86,'2021-01-23'),('Xander',89,'2021-01-24'),
('York',92,'2021-01-25'),('Zara',95,'2021-01-26');
INSERT INTO student (name, age, create_time)
SELECT `name`, `age`, DATE_ADD('2021-01-01', INTERVAL `id` DAY) FROM `student`;
COMMIT;

接下来,我们分别演示如何导致索引失效:

  1. 对索引列进行函数操作:

我们使用下面的查询语句查询2021年4月份创建的学生记录:

SELECT * FROM student WHERE YEAR(create_time) = 2021 AND MONTH(create_time) = 4;

可以看到,虽然create_time上有一个索引,但是这个索引无法被使用,因为我们对create_time进行了YEAR和MONTH函数操作:

id  name    age create_time
--------------------------------------------------
909 Alex    20  2021-04-09 00:00:00
911 Carl    26  2021-04-11 00:00:00
913 Eric    32  2021-04-13 00:00:00
915 Grace   38  2021-04-15 00:00:00
917 Ivy 44  2021-04-17 00:00:00
919 Kelly   50  2021-04-19 00:00:00
921 Lily    53  2021-04-21 00:00:00
923 Mike    56  2021-04-23 00:00:00
925 Oliver  62  2021-04-25 00:00:00
927 Paul    65  2021-04-27 00:00:00
929 Robert  71  2021-04-29 00:00:00

如果我们将查询改为下面的形式,就可以使用索引了:

SELECT * FROM student WHERE create_time >= '2021-04-01' AND create_time < '2021-05-01';
  1. 在联合索引中未按照顺序使用:

我们使用下面的查询语句查询年龄大于18岁且名字为Alex的学生记录:

SELECT * FROM student WHERE name = 'Alex' AND age > 18;

可以看到,虽然(name, age)上有一个联合索引,但是这个索引无法被使用,因为查询时未按照索引中列的顺序使用,如果我们将查询改为下面的形式,就可以使用索引了:

SELECT * FROM student WHERE age > 18 AND name = 'Alex';

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MySQL导致索引失效的几种情况 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • Python对接 xray 和微信实现自动告警

    Python 对接 Xray 和微信实现自动告警的完整攻略可以分为以下几个步骤: 安装 Xray 配置 Xray 编写 Python 脚本 配置微信告警 下面我们将针对每个步骤进行详细的介绍和示例说明。 安装 Xray Xray 是一款强大的网络安全检测工具,它可以帮助我们识别和发现 Web 应用程序的漏洞。在使用 Python 对接 Xray 前,需要先安…

    database 2023年5月22日
    00
  • DBMS中游标和触发器的区别

    接下来我将详细解释DBMS中游标和触发器的区别。 游标和触发器的定义 游标和触发器都是DBMS中的重要概念,但它们的含义却不同。 游标:是在SQL语句执行中,对于一组数据结果的读取,可以将其理解为指针,指向关系数据库系统的某行,并允许程序对该行执行操作。因此,游标是一种用于遍历结果集的高级机制,可以理解为一个指向表格中数据行的指针。 触发器:是一段存储在关系…

    database 2023年3月27日
    00
  • SQL 找出最大和最小的记录

    要找出 SQL 数据库中某个表中最大和最小的记录,我们需要使用 MAX() 和 MIN() 函数。以下是实现该功能的步骤和示例: 步骤1:检查数据库 在开始查询之前,请确保您有可用的数据库和表。如果没有,请创建表并插入一些记录以用于查询。 步骤2:使用 MAX() 和 MIN() 函数 使用 MAX() 函数找出表中最大的记录,并使用 MIN() 函数找出最…

    database 2023年3月27日
    00
  • MySQL的意向共享锁、意向排它锁和死锁

    MySQL意向锁和死锁攻略 意向锁 MySQL中有两种意向锁:意向共享锁(IS)和意向排它锁(IX)。当一个事务请求一张表的排它锁或者共享锁时,MySQL会先判断表是否已经被其它事务加了锁。若没有加锁,则直接获取锁;若被加锁,则会判断待加的锁类型。若是要请求共享锁,则会在表上加意向共享锁(IS);若是要请求排它锁,则会在表上加意向排它锁(IX)。意向锁只是一…

    database 2023年5月19日
    00
  • CodeIgniter针对数据库的连接、配置及使用方法

    下面是本文对于“CodeIgniter针对数据库的连接、配置及使用方法”的完整攻略。 1. CodeIgniter数据库配置 CodeIgniter支持多种数据库,并且在连接和使用数据库时非常方便。下面我们来讲解CodeIgniter配置数据库的方法。 1.1 配置文件 CodeIgniter的数据库配置文件位于application/config/data…

    database 2023年5月19日
    00
  • linux下redis的最佳实践(Master-Slave)

    本文演示了redis在同一台linux上的安装及运行多个实例,并演示了主从复制,以及如何进行主从的切换。 1. 下载 $ wget http://download.redis.io/releases/redis-3.0.7.tar.gz 2. 解压缩 $ tar xzf redis-3.0.7.tar.gz 3. 编译 $ cd redis-3.0.7 $ …

    Redis 2023年4月11日
    00
  • python可以用哪些数据库

    简述Python可以用哪些数据库Python可以使用多种不同类型的数据库,包括关系型数据库和非关系型数据库。下面是Python可以使用的一些常见的数据库: MySQL: 一个流行的开源关系型数据库。 PostgreSQL: 另一个流行的开源关系型数据库。 Oracle: 一种商业级别的关系型数据库。 MongoDB: 一个流行的开源非关系型数据库。 Redi…

    database 2023年5月22日
    00
  • PostgreSQL使用MySQL外表的步骤详解(mysql_fdw)

    PostgreSQL使用MySQL外表的步骤详解(mysql_fdw) MySQL外表(fdw)允许PostgreSQL服务器访问远程MySQL服务器上的数据,就好像它们存在于PostgreSQL本地一样。这可以极大地简化数据集成,特别是在需要合并来自不同数据库的数据时。 下面是使用mysql_fdw的步骤以及具体操作: 步骤一:安装mysql_fdw 首先…

    database 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部