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

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日

相关文章

  • createObjectURL方法实现本地图片预览

    下面是关于 “createObjectURL方法实现本地图片预览” 的完整攻略,包括了示例说明。 简介 createObjectURL 是 HTML5 新增的 API,用于将 Blob 对象或 File 对象转换为 URL。在浏览器中使用该 URL 可以进行本地文件预览,常用于图片和视频的预览。 示例 下面是一个简单的示例,实现点击按钮上传图片并显示预览图。…

    database 2023年5月22日
    00
  • DBMS中的位图索引

    位图索引是一种特殊类型的索引,用于在DBMS中加速条件查询。具体的实现方法是,对于表中某个特定的列,将其所有可能值所对应的行编号(或者行的位置)用二进制的0和1表示出来,形成一个位图vector。这样,在查询时,由于查询条件本质上也是一个值,因此只需要在该值所对应的位图vector中找到所有1的位置即可找到满足条件的行。 下面我们来详细讲解位图索引的实现步骤…

    database 2023年3月27日
    00
  • mysql8.0.23 linux(centos7)安装完整超详细教程

    下面是“mysql8.0.23 linux(centos7)安装完整超详细教程”的完整攻略: 准备工作 在开始安装之前,首先需要满足一些前置条件: 已经拥有一台安装好CentOS 7的服务器。 确保服务器拥有基本的系统管理权限,包括sudo权限和root用户访问权限。 确保服务器已经安装了依赖软件包,如gcc,openssl,cmake等。 下载MySQL …

    database 2023年5月22日
    00
  • linux下安装redis及redis的php扩展

    http://hi.baidu.com/mucunzhishu/item/ead872ba3cec36db84dd798c CentOS 下 Redis 2.2 安装配置详解 一. 关于 Redis Redis是一种高级 key-value 数据库。它跟 memcached 类似,不过数据可以持久化,而且支持的数据类型很丰富。它在保持键值数据库简单快捷特点的…

    Redis 2023年4月11日
    00
  • 百万级别知乎用户数据抓取与分析之PHP开发

    以下是百万级别知乎用户数据抓取与分析之PHP开发的完整攻略: 1. 准备工作 在开始之前,需要先安装PHP环境和相关扩展,如CURL扩展、SimpleXML扩展等。 除此之外,还需要获取知乎的API访问令牌,可以参考知乎开放平台官方文档进行获取和配置。 2. 数据抓取 在完成准备工作之后,就可以开始进行数据抓取了。 2.1. 获取用户ID列表 首先需要获取一…

    database 2023年5月22日
    00
  • 通过两种方式增加从库——不停止mysql服务

    本文将介绍通过两种方式增加MySql从库,而不需要停止MySql主服务。两种方式分别为基于GTID的复制和基于数据库备份的复制。 1. 基于GTID的复制 GTID是MySQL从5.6版本中引入的特性,用于在主从复制环境中解决多主复制冲突的问题。在增加从库时,使用GTID能够避免重复数据问题。 1.1 步骤一:启用GTID 在MySQL主服务器上,编辑my.…

    database 2023年5月22日
    00
  • 详解Spring中的Transactional属性

    详解Spring中的Transactional属性 在Spring框架中,事务管理是非常重要且常用的一个功能。而@Transactional属性是管理事务的重要属性之一。本文将详细讲解@Transactional属性,并提供一些示例来解释常见的用途。 什么是@Transactional属性? @Transactional属性用于指定带有事务性质的方法。它可以…

    database 2023年5月21日
    00
  • C基础 redis缓存访问详解

    C基础 redis缓存访问详解 什么是Redis Redis是一个基于Key-Value存储的NoSQL数据库,完全开源免费。Redis支持多种数据结构,如字符串、哈希表、列表、集合和有序集合,并且提供了丰富的操作命令以及事务支持。 Redis在C语言中的应用 当我们在C语言中需要使用Redis时,需要借助Redis官方提供的hiredis库,hiredis…

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