MySQL 索引失效案例:字符集不匹配的隐蔽影响

引言

在 MySQL 数据库世界里,索引失效往往是性能问题的罪魁祸首。你是否曾遇到过这样的情况:明明加了索引,查询却慢如蜗牛?你是否曾以为小表查询就一定高效?本文将揭示一个真实的案例,一个容易被忽视的“隐形杀手”—— 字符集不匹配,它如何悄无声息地破坏你的索引,让你的查询在小表上也能崩溃。更令人惊讶的是,LIMIT 子句竟然在某种程度上“掩盖”了这个问题的严重性,直到 ORDER BY 的出现,才让真相大白。准备好迎接这场关于 MySQL 字符集、索引、LIMITORDER BY 的深度探险了吗?让我们一起揭开这个性能谜团!

问题描述

我们有两个表:wdm_recruit_sett (患者结算表) 和 sys_user (用户表),数据量都在 5000 条左右。 我们进行以下两种查询:

查询 1 (不带 ORDER BY):

SELECT1
FROMwdm_recruit_sett wrsLEFT JOIN sys_user su ON su.id = wrs.user_id
LIMIT 10;

查询 2 (带 ORDER BY):

SELECT1
FROMwdm_recruit_sett wrsLEFT JOIN sys_user su ON su.id = wrs.user_id
ORDER BY wrs.create_time DESC  --  create_time 没有索引
LIMIT 10;

表结构(简化):

wdm_recruit_sett

CREATE TABLE wdm_recruit_sett (id VARCHAR(32) NOT NULL PRIMARY KEY,user_id VARCHAR(64) NULL,create_time DATETIME NULL,-- ... 其他字段 ...INDEX idx_user_id (user_id)
);  -- 字符集:数据库默认的 utf8mb4

sys_user

CREATE TABLE sys_user (id VARCHAR(32) NOT NULL PRIMARY KEY-- ... 其他字段 ...
) CHARACTER SET utf8;  -- 字符集:显式指定为 utf8

性能差异巨大:

  • 查询 1 (无 ORDER BY):执行时间在 毫秒级
  • 查询 2 (有 ORDER BY):执行时间飙升至 十几秒

问题分析

我们分别查看两个查询的 EXPLAIN 执行计划:

查询 1 (无 ORDER BY) 的执行计划 :

-- (图片中的 EXPLAIN 输出)
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: wrspartitions: NULLtype: ALL
possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: 5241filtered: 100Extra: NULL
*************************** 2. row ***************************id: 1select_type: SIMPLEtable: supartitions: NULLtype: ALL
possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: 5953filtered: 100Extra: Using where; Using join buffer (Block Nested Loop)

查询 2 (带 ORDER BY) 的执行计划 (来自之前的图片):

-- (之前的图片中的 EXPLAIN 输出)
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: wrspartitions: NULLtype: ALL
possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: 5241filtered: 100Extra: Using temporary; Using filesort
*************************** 2. row ***************************id: 1select_type: SIMPLEtable: supartitions: NULLtype: ALL
possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: 5953filtered: 100Extra: Using where; Using join buffer (Block Nested Loop)

分析要点:

  1. 两个查询都是全表扫描 (type: ALL): 由于 sys_user.id (utf8) 和 wdm_recruit_sett.user_id (utf8mb4) 的字符集不匹配,MySQL 无法使用任何索引进行连接,导致对两个表都进行了全表扫描。
  2. LIMIT 10 的“掩盖”作用(查询 1): 在没有 ORDER BY 的情况下,MySQL 在找到 10 条匹配的记录后就可以停止扫描,即使是全表扫描,由于只需要很少的数据,执行速度也很快(毫秒级)。 这 掩盖 了字符集不匹配导致的索引失效问题。
  3. ORDER BY 暴露问题(查询 2): ORDER BY wrs.create_time DESC 迫使 MySQL 必须对 wrs 表进行 完整 的全表扫描,并进行文件排序 (filesort),才能找到最大的 10 条记录。 这时,全表扫描的代价就完全暴露出来了,导致执行时间飙升至十几秒。
  4. possible_keysNULL: 即使 sys_user 有主键,字符集不匹配导致优化器在评估阶段就排除了所有索引.

根本原因:字符集不匹配

sys_user.id (utf8) 和 wdm_recruit_sett.user_id (utf8mb4) 的字符集不一致,是导致索引失效、全表扫描的根本原因。

解决方案:统一字符集

sys_user 表的 id 字段(以及其他相关文本字段)的字符集修改为 utf8mb4,与 wdm_recruit_sett 表一致。

-- (请务必先备份数据!)
-- 1. 查找并删除引用 sys_user.id 的外键约束 (如果有)
-- 2. 删除 sys_user 表的主键
ALTER TABLE sys_user DROP PRIMARY KEY;
-- 3. 修改 id 列的字符集
ALTER TABLE sys_user MODIFY id VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
-- 4. 重新添加主键
ALTER TABLE sys_user ADD PRIMARY KEY (id);

修改字符集后, 不管有没有order by,MySQL 都能高效地利用索引,性能将得到极大提升。 同时, 建议在wrs表上创建create_time索引, 以优化order by

总结

这个案例揭示了一个容易被忽视的 MySQL 性能陷阱:

  1. 字符集不匹配是隐蔽的性能杀手: 它会导致索引失效,即使在小表上也会产生严重影响。
  2. LIMIT 可能会掩盖问题: 在没有 ORDER BY 的情况下,LIMIT 可能会让全表扫描看起来很快,从而掩盖了潜在的性能问题。
  3. ORDER BY 暴露问题: ORDER BY 非索引列会迫使 MySQL 进行完整扫描和排序,放大了潜在的性能问题。
  4. EXPLAIN 是诊断利器: EXPLAIN 可以帮助我们看清 MySQL 的执行计划,揭示问题的根源。
  5. 数据库设计规范至上: 从一开始就应该统一使用 utf8mb4 字符集,避免后期出现各种难以排查的性能问题。

希望这个案例能帮助大家更深入地理解 MySQL 的查询优化,避免类似的性能陷阱。

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

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

相关文章

Golang GORM系列:GORM 高级查询教程

有效的数据检索是任何程序功能的基础。健壮的Go对象关系映射包(称为GORM)除了标准的CRUD操作之外,还提供了复杂的查询功能。这是学习如何使用GORM进行高级查询的综合资源。我们将涵盖WHERE条件、连接、关联、预加载相关数据,甚至涉…

常见的数据仓库有哪些?

数据仓库(Data Warehouse,简称数仓)是企业用于存储、管理和分析大量数据的重要工具,其核心目标是通过整合和处理数据,为决策提供高质量、一致性和可信度的数据支持。在构建和使用数仓时,选择合适的工具和技术至关重要。以下是常见的数仓工具及其特点的详细介绍: 1. Hiv…

搜维尔科技在动作捕捉与动画制作、汽车制造与安全测试、机器人与自动化领域的一些案例

动作捕捉与动画制作领域 1.逼真的手部和面部动画制作:动画师施先生利用搜维尔科技代理的Xsens套装、Manus VR手套和Faceware的面部动作捕捉系统,捕捉短片中人物的手部和面部动作,再将数据重新定位到角色骨架上并调整,最终在虚幻引…

HTTP3原理解析和实战应用

http协议原理解析 HTTP1.1改动 keeplive 在http1.0版本中http连接会在每次请求都会发起连接, 并且每次连接在保证安全性都需要建立三次握手, 每次请求后就立即断开连接, 下次请求就还需要重新建立连接.这样就提升了请求的复杂度. keeplive就使得每次建立连接后可以多次请求…

【分布式理论9】分布式协同:分布式系统进程互斥与互斥算法

文章目录 一、互斥问题及分布式系统的特性二、分布式互斥算法1. 集中互斥算法调用流程优缺点 2. 基于许可的互斥算法(Lamport 算法)调用流程优缺点 3. 令牌环互斥算法调用流程优缺点 三、三种算法对比 在分布式系统中,多个应用服务可能会同时…

VMware Windows_10_x64 安装 VM Tools 后无法将本机文件复制到虚拟机

有一种情况,安装VM Tools死活安装不上去。这时不要急不要慌,重启本机就好了(本人情况就是如此)。 windows键 R 输入 service.msc 打开服务管理器 找到Virtual Disk服务,选择属性设置为自动,应用后启用服…

uniapp 编译生成鸿蒙正式app步骤

1,在最新版本DevEco-Studio工具新建一个空项目并生成p12和csr文件(构建-生成私钥和证书请求文件) 2,华为开发者平台 根据上面生成的csr文件新增cer和p7b文件,分发布和测试 3,在最新版本DevEco-Studio工具 文…

AI+智能中台企业架构设计_重新定义制造(46页PPT)

本文档主要探讨了“中台”的概念及其在制造领域的应用,通过百度中台技术案例,展示了如何利用ABCIOT(人工智能、大数据、云计算和物联网)重新定义制造业。中台被定义为企业内部核心管理平台,包括微服务业务平台、组织创…

基于Java的分布式系统架构设计与实现

Java在大数据处理中的应用:基于Java的分布式系统架构设计与实现 随着大数据时代的到来,数据处理的规模和复杂性不断增加。为了高效处理海量数据,分布式系统成为了必不可少的架构之一。而Java,凭借其平台独立性、丰富的生态系统以…

MySQL数据库入门到大蛇尚硅谷宋红康老师笔记 基础篇 part 11

第11章_数据处理之增删改 首先得先有一个表: #0. 储备工作 USE atguigudb;CREATE TABLE IF NOT EXISTS emp1( id INT, name VARCHAR(15), hire_date DATE, salary DOUBLE(10,2) );DESC emp1;SELECT * FROM emp1; 1.增加数据 #方式1:一条一条的添加…

Java多线程——线程池的使用

线程饥饿死锁 在单线程的Executor中,如果任务A将任务B提交给同一个Executor,并且等待任务B的结果,就会引发死锁线程池中所有正在执行任务的线程由于等待其他仍处于工作队列中的任务而阻塞 执行时间较长的任务 执行时间较长的任务不仅会造成…

通过C模块中的Python API访问数组的数组

在 C 模块中通过 Python API 访问数组的数组(即多维数组)涉及到使用 Python C API 来处理 Python 对象和数据结构。在 C 代码中访问这种数据结构时,我们可以使用 Python 的对象访问方式,例如 PyList 或 PyArray(如果你…

【IDEA】2017版本的使用

目录 一、常识 二、安装 1. 下载IDEA2017.exe 2. 安装教程 三、基本配置 1. 自动更新关掉 2. 整合JDK环境 3. 隐藏.idea文件夹和.iml等文件 四、创建Java工程 1. 新建项目 2. 创建包结构,创建类,编写main主函数,在控制台输出内容。…

物联网智能语音控制灯光系统设计与实现

背景 随着物联网技术的蓬勃发展,智能家居逐渐成为现代生活的一部分。在众多智能家居应用中,智能灯光控制系统尤为重要。通过语音控制和自动调节灯光,用户可以更便捷地操作家中的照明设备,提高生活的舒适度与便利性。本文将介绍一…

利用HTML和css技术编写学校官网页面

目录 一,图例展示 二,代码说明 1,html部分: 【第一张图片】 【第二张图片】 【第三张图片】 2,css部分: 【第一张图片】 【第二张图片】 【第三张图片】 三,程序代码 一,…

学习笔记十九:K8S生成pod过程

K8S生成pod过程 流程图具体生成过程用户提交 Pod 定义API Server 处理请求调度器分配节点(Scheduling)目标节点上的 Pod 创建网络配置状态上报与监控控制器管理(Controller Manager)就绪与服务发现 关键错误场景高级特性 流程图 具…

(一)Axure制作移动端登录页面

你知道如何利用Axure制作移动端登录页面吗?Axure除了可以制作Web端页面,移动端也是可以的哦,下面我们就一起来看一下Axure制作移动端登录页面的过程吧。 第一步:从元件中拖入一个矩形框,并设置其尺寸为:37…

【C++】——精细化哈希表架构:理论与实践的综合分析

先找出你的能力在哪里,然后再决定你是谁。 —— 塔拉韦斯特弗 《你当像鸟飞往你的山》 目录 1. C 与哈希表:核心概念与引入 2. 哈希表的底层机制:原理与挑战 2.1 核心功能解析:效率与灵活性的平衡 2.2 哈希冲突的本质&#x…

第5章 数据库系统(选择|案例|论文)(重点★★★★★)

5.1 数据库管理系统1 数据库是长期存储在计算机内的、有组织的、可共享的数据集合,数据库系统是指在计算机信息系统中引入数据库后的系统,一般由数据库、数据库管理系统 (DataBaseManagement System,DBMS)、应用系统、数据库管理员(DataBase…

jenkins备份还原配置文件

下载ThinBackup插件 方式1 从插件市场直接下载 Manage Jenkins->Manage Plugins->可选插件搜索 注意:有时可能因为网络或者版本问题下载不了,好像是默认下载最新版本,可选择手动安装! 方式二 手动安装插件 点击查看手…