MySQL 有多个普通索引时会取哪一个索引?

我们都知道MySQL在查询时底层会进行索引的优化,假设有两个普通索引,且where 后面也根据这两个普通索引查询数据,那么执行查询语句时会使用到那个索引?

为了方便演示,新建users表,新建idx_name、idx_city这两个普通索引如下:

CREATE TABLE users (id INT PRIMARY KEY,name VARCHAR(50) ,age INT,city VARCHAR(50) ,INDEX idx_name (name),INDEX idx_city (city)
) DEFAULT CHARSET=utf8mb4i;
INSERT INTO users (id, name, age, city)
VALUES(1, '张三', 25, '北京'),(2, '李四', 30, '上海'),(3, '王五', 40, '广州'),(4, '赵六', 35, '深圳'),(5, '张三', 28, '上海');

1)根据单个索引查询

根据name 查询数据时,如下图key = idx_name ,即走了idx_name的索引

explain select * from users where name = '张三';

image-20231124223736971

根据city查询数据时,如下图key = idx_city ,即走了idx_city的索引

image-20231124223934641

2)根据多个普通索引查询

示例1:

根据name和city查询,并且name和city能够定位到一条数据

explain select * from users where name = '张三' and city = '上海';

image-20231124224604957

即使没有复合索引,优化器也可以选择使用索引合并策略。它可以使用 idx_name 索引定位满足 name = '张三' 的行,然后使用 idx_city 索引在之前的结果集上进行进一步筛选,以满足 city = '上海' 的条件。

示例2:

根据name和city查询,并且单独查询name时,name = ‘张三’ 有两条记录,单独查询city时,city=‘广州’ 有一条记录

explain select * from users where name = '张三' and city = '广州';

image-20231124225014062

此时优化器会走idx_city索引,这是因为如果走idx_name索引要查询两次,根据idx_city一次查询就能定位到具体的数据,因此此处优化器采用idx_city作为索引。

同样执行如下SQL也是走的idx_city的索引,因为city='北京’的记录只有一条

explain select * from users where name = '张三' and city = '北京';

再来看看下面的这个SQL语句,会走那个索引呢?

explain select * from users where name = '李四' and city = '上海';

image-20231124225751394

如上图,当根据name = '李四’查询出来数据只有一条、city='上海’有两条数据,最终结果走的是idx_name索引

示例3:

explain select * from users where   city = '广州' and name = '赵六';explain select * from users where name = '赵六' and city = '广州';

上面两个SQL语句查询执行计划时发现,两条语句的查询计划是一致的,都是直接走idx_name索引,不管where条件后面name和city的先后顺序

image-20231124231026353

原因是,如上图执行计划中possiblie_keys = idx_name,idx_city。因为idx_name 先创建,所以优化器会先判断是否走了idx_name索引,name=‘赵六’ 刚好检索出一条记录

实例4

explain select * from users where   city = '广州' and name = '张三';

image-20231124232144601

这个时候走的是idx_city的索引,不管where条件后面name和city的顺序。

案例5

explain select * from users where   city = '广州' and name = '王五';
explain select * from users where   name = '王五' and city = '广州' ;

image-20231124232553815

以上两个SQL都走了idx_name的索引,和案例1有一些区别,案例1中,name = ‘张三’ 或者 city = '上海’都能查询多多行数据,如果使用联合索引的话效率更高。案例5中,由于根据idx_name就能把这一行的数据给定位到了,因此采用idx_name索引就能满足。

以上都是MySQL优化器自动选择索引,那如果我们想强制使用自己的索引可以使用 force index,具体如下

查询name = ‘张三’ 、city = '广州’的数据,我们通过查询计划得知走的是idx_city索引。

explain select * from users where name = '张三' and city = '广州';

在这里插入图片描述
如果我们强制使用idx_name索引,看看效果,发现已经强制使用idx_name索引
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/167884.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端vue导出PPT,使用pptxgen.js

前言 公司新需求需要导出ppt给业务用,查阅资料后发现也挺简单的,记录一下。 如有不懂的可以留言!!! 1.安装包 npm install pptxgenjs --save2.引入包 在需要使用的文件中引入 import Pptxgenfrom "pptxgenjs&…

Oracle研学-介绍及安装

一 ORACLE数据库特点: 支持多用户,大事务量的事务处理数据安全性和完整性控制支持分布式数据处理可移植性(跨平台,linux转Windows) 二 ORACLE体系结构 数据库:oracle是一个全局数据库,一个数据库可以有多个实例,每个…

nodejs+vue+python+PHP+微信小程序-留学信息查询系统的设计与实现-安卓-计算机毕业设计

1、用户模块: 1)登录:用户注册登录账号。 2)留学查询模块:查询学校的入学申请条件、申请日期、政策变动等。 3)院校排名:查询国外各院校的实力排名。 4)测试功能:通过入学…

Spring Boot WebSocket 客户端

介绍 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它可以提供实时的、双向的数据传输。Spring Boot 提供了对 WebSocket 的支持,我们可以使用 Spring Boot WebSocket 客户端来连接到 WebSocket 服务器,并进行实时通信。 本文将…

python-选择排序

选择排序是一种简单直观的排序算法,它的基本思想是每一轮选择未排序部分的最小元素,然后将其放到已排序部分的末尾。这个过程持续进行,直到整个数组排序完成。(重点:通过位置找元素) 以下是选择排序的详细步骤和 Python 实现&…

HarmonyOS应用开发实战—登录页面【ArkTS】

文章目录 本页面实战效果预览图一.HarmonyOS应用开发1.1HarmonyOS 详解1.2 ArkTS详解二.HarmonyOS应用开发实战—登录页面【ArkTS】2.1 ArkTS页面源码2.2 代码解析2.3 心得本页面实战效果预览图 一.HarmonyOS应用开发 1.1HarmonyOS 详解 HarmonyOS(鸿蒙操作系统)是华为公司…

小程序首页白屏优化,并举例说明

小程序首页白屏优化 小程序首页白屏优化是指在用户进入小程序首页时,能够尽快展示内容,避免出现长时间的白屏加载状态,提升用户体验。以下是一些常见的小程序首页白屏优化方法: 减少首屏请求:尽量减少首页需要请求的资…

js粒子效果(一)

效果: 代码: <!doctype html> <html> <head><meta charset"utf-8"><title>HTML5鼠标经过粒子散开动画特效</title><style>html, body {position: absolute;overflow: hidden;margin: 0;padding: 0;width: 100%;height: 1…

DELL MD3600F存储重置管理软件密码

注意&#xff1a;密码清除可能会导致业务秒断&#xff0c;建议非业务时间操作 针对一台控制器操作即可&#xff0c;另一控制器会同步操作 重置后密码为空&#xff01; 需求&#xff1a;重置存储管理软件密码 管理软件中分配物理磁盘时提示输入密码(类似是否了解风险确认操作的提…

华为OD机试 - 二叉树计算(Java JS Python C)

目录 题目描述 输入描述 输出描述 用例 题目解析 JS算法源码 Java算法源码

io.lettuce.core.RedisCommandExecutionException

io.lettuce.core.RedisCommandExecutionException: ERR invalid password ERR invalid password-CSDN博客 io.lettuce.core.RedisCommandExecutionException /** Copyright 2011-2022 the original author or authors.** Licensed under the Apache License, Version 2.0 (the…

Rust UI开发(一):使用iced构建UI时,如何在界面显示中文字符

注&#xff1a;此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库&#xff0c;用于为rust语言程序构建UI界面。 iced的基本逻辑是&#xff1a; UI交互产生消息message&#xff0c;message传递给后台的update&#xff0c;在这个函数中编写逻辑&#xff0c;然后通过…

2023-11-24--oracle--实验--[Merge 语句]

oracle--实验---Merge语句 1.认知Merge 语句 • merge 语句是 sql 语句的一种。在 SQL server 、 Oracle 数据库中可用&#xff0c; MySQL 中不可用。 • merge 用来合并 update 和 insert 语句。目的&#xff1a;通过 merge 语句&#xff0c;根据一张表&#xff08; 原数据表…

IOS免签封装打包苹果APP的方法

IOS免签app封装打包苹果APP的方法如下&#xff1a; 准备一个未签名的IPA文件。获取一个企业证书或个人证书&#xff0c;用于签名IPA文件。将证书添加到Keychain Access中。安装iOS App Signer&#xff08;可以在网上找到相关下载链接&#xff09;。打开iOS App Signer&#xf…

AT360-6T GNSS 单频高精度授时模块特性参数

AT360-6T 模块具有高灵敏度、低功耗、低cost等优势&#xff0c;可以满足电力授时&#xff0c;通信授时等领域的应用。AT360-6T特点&#xff1a; 1.支持北斗二代/北斗三代信号 2.高精度授时 3.可靠性授时 实时高精度授时 AT360-6T 系列模块的授时秒脉冲抖动可以达到 10ns&am…

Vue学习笔记-搭建Vuex

1.概念 在Vue实现集中式状态&#xff08;数据&#xff09;管理的一个插件&#xff0c;对Vue中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间的通信方式&#xff0c;适用于任意组件间的通信 2.使用场景 多个组件需要共享数据时…

Mysql存储引擎分类

Mysql存储引擎分类&#xff1a; 在选择存储引擎时&#xff0c;应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统&#xff0c;还可以根据实际情况选择多种存储引擎进行组合。 InnoDB: 是Mysql的默认存储引擎&#xff0c;支持事务、外键。如果应用对事务的完整性有…

杰发科技AC7801——ADC软件触发的简单使用

前言 7801资料读起来不是很好理解&#xff0c;大概率是之前MTK的大佬写的。在此以简单的方式进行描述。我们做一个简单的规则组软件触发Demo。因为规则组通道只有一个数据寄存器&#xff0c;因此还需要用上DMA方式搬运数据到内存。 AC7801的ADC简介 7801的ADC是一种 12 位 逐…

一文学会qml自定义组件

文章目录 最简单的自定义控件:自定义按钮组件添加自定义信号在QML中,自定义组件通常是通过创建一个新的QML文件来实现的,这个文件定义了组件的属性、信号、槽以及界面。你可以将这个组件看作是一个可重用的模块,它可以在不同的QML场景中使用,而不需要重复编写代码。 以下…

洛谷P1157组合的输出 递归:我他又来辣

没没没没没没没错&#xff0c;这是一道简单的递归&#xff08;其实是深搜加回溯) 我不管&#xff0c;我说是递归就是递归。 上题干&#xff1a; 题目描述 排列与组合是常用的数学方法&#xff0c;其中组合就是从 n 个元素中抽出 r个元素&#xff08;不分顺序且 r≤n&#x…