【MySQL】MySQL不走索引的情况分析

news2024/11/23 21:33:54

未建立索引

当数据表没有设计相关索引时,查询会扫描全表。

create table test_temp
(
    test_id     int auto_increment
        primary key,
    field_1     varchar(20) null,
    field_2     varchar(20) null,
    field_3     bigint      null,
    create_date date        null
);
explain 
select * from test_temp where field_1 = 'testing0';

在这里插入图片描述

建议

查询频繁是数据表字段增加合适的索引。

查询结果集是原表中的大部分数据

当数据库查询命中索引时,数据库会首先利用索引列的值定位到对应的数据节点。这个数据节点上记录了对应数据行的行标识符(Row Identifier)。然而,如果查询需要获取该行其他列的数据,就需要进行回表操作。

在回表操作中,数据库会使用行标识符再次访问数据节点或磁盘上的实际数据行,以获取完整的数据。这个过程被称为回表。回表操作可能会增加额外的磁盘访问和数据检索的开销,因此,在某些情况下,当MySQL判断回表所需的资源大于直接扫描全表时,它可能选择不走索引,而是执行全表扫描。
在这里插入图片描述

建议

  1. 索引覆盖:酌情考虑创建包含查询所需列的索引,查询结果集全部被索引覆盖,无需回表。
  2. 调整查询语句:查询必要的列、使用Join语句优化查询语句,减少回表次数。
  3. 当表数据量较大时,需考虑其他存储服务。

使用函数、隐式转换

使用函数

在这里插入图片描述

在这里插入图片描述

隐式转换

数据准备:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for products
-- ----------------------------
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
  `id` int NOT NULL,
  `name` varchar(255) NOT NULL,
  `price` decimal(10,2) NOT NULL,
  `description` text,
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `type` tinyint NOT NULL COMMENT '商品类型',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of products
-- ----------------------------
BEGIN;
INSERT INTO `products` VALUES (1, 'Product A', 10.99, 'This is the description for Product A', '2023-08-11 03:47:06', '2023-08-11 03:49:24', 1);
INSERT INTO `products` VALUES (2, 'Product B', 19.99, 'This is the description for Product B', '2023-08-11 03:47:07', '2023-08-11 03:49:24', 2);
INSERT INTO `products` VALUES (3, 'Product C', 5.99, 'This is the description for Product C', '2023-08-11 03:47:07', '2023-08-11 03:49:25', 3);
INSERT INTO `products` VALUES (4, 'Product D', 8.49, 'This is the description for Product D', '2023-08-11 03:47:07', '2023-08-11 03:49:24', 2);
INSERT INTO `products` VALUES (5, 'Product E', 15.99, 'This is the description for Product E', '2023-08-11 03:47:07', '2023-08-11 03:49:25', 2);
INSERT INTO `products` VALUES (6, 'Product F', 12.99, 'This is the description for Product F', '2023-08-11 03:47:08', '2023-08-11 03:49:24', 2);
INSERT INTO `products` VALUES (7, 'Product G', 7.99, 'This is the description for Product G', '2023-08-11 03:47:08', '2023-08-11 03:49:24', 2);
INSERT INTO `products` VALUES (8, 'Product H', 9.99, 'This is the description for Product H', '2023-08-11 03:47:08', '2023-08-11 03:49:24', 2);
INSERT INTO `products` VALUES (9, 'Product I', 14.99, 'This is the description for Product I', '2023-08-11 03:47:09', '2023-08-11 03:49:24', 2);
INSERT INTO `products` VALUES (10, 'Product J', 11.99, 'This is the description for Product J', '2023-08-11 03:47:09', '2023-08-11 03:49:24', 2);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

增加索引

ALTER TABLE products
ADD INDEX idx_type (type);

复现:

explain
select * from products where type in ('1','2');

由于type是tinyint类型,因此,以上SQL等效为:

SELECT * FROM products WHERE type in CAST('1' AS tinyint,'2' as tinyint);

在这里插入图片描述

由于使用了CAST()函数,会导致不走索引的现象。
还有一种情况是:在关联查询时,驱动表关联字段两者排序规则不一致时也会导致不走索引。

in/not in <>条件导致不走索引

in、not in、<>不走索引的原因是相似的,以下基于in语句分析。
in条件导致不走索引的情况:

in条件过多

explain
select * from products where type in (1,2,3,4,5,6,7);

如果 IN 条件中包含太多的值,超出了数据库管理系统的限制,它可能会选择不使用索引。

建议

当in条件中的数据是连续时,可以使用between and代替in。
分而治之,将一次查询分为多次查询,最后取并集。
使用UNION语句,类似方案一,只不过该方案是在SQL层面完成。

SELECT column1, column2, ...
FROM your_table
WHERE column IN (value1, value2, ..., valueN)
UNION
SELECT column1, column2, ...
FROM your_table
WHERE column IN (valueN+1, valueN+2, ..., valueM)

统计信息不准确

SHOW ENGINE INNODB STATUS;

该命令会查询出MySQL Inndb存储引擎的操作情况,信息包含Innodb各种统计信息:

  • Inserts:已插入的行数。
  • Updates:已更新的行数。
  • Deletes:已删除的行数。
  • Reads:已读取的行数。

innodb表的统计信息并不是实时统计更新,如果统计信息和实际的索引信息差异很大,就会导致优化器计算各个索引成本后,做出非预期的选择。出现这种现象的场景是:当有大量数据在短时间内落库时,Innodb还没更新统计相关信息,此时来了一个查询,MySQL会基于历史数据做出错误的判断:当前表数据量少,不走索引更高效。

建议

基于此问题的解决方案是:手动更新相关统计数据。
请参考:
www.modb.pro/db/46678

like语句

like语句无法命中索引的情况:

前导通配符:%value
通配符在字符串的中间:value%value
通配符"_"出现在开头

建议

尽量避免在模式的开头使用前导通配符 %
如果无法避免第一种,根据实际业务和查询语句考虑使用后缀索引
将通配符 % 放在模式的末尾,以便进行前缀匹配。
如果需要在模式的中间使用通配符 %,可以考虑使用全文搜索引擎或其他更适合模式匹配的技术。
对于固定长度的模式匹配,可以考虑使用其他操作符,如 = 或 <>

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

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

相关文章

C++多态与虚函数的原理与关系

C多态 多态可以分为编译时的多态和运行时的多态。前者主要是指 函数的重载&#xff08;包括运算符的重载&#xff09;、对重载函数的调用&#xff0c;在编译时就能根据实参确定应该调用哪个函数&#xff0c;因此叫编译时的多态&#xff1b;而后者则和继承、虚函数等概念有关。…

智慧交通项目实战全流程-DeepSort多目标跟踪车道线检测

1. 项目介绍 2. 算法库 2.1 numba介绍 numba是⼀个⽤于编译Python数组和数值计算函数的编译器&#xff0c;这个编译器能够⼤幅提⾼直接使⽤Python编写的函数的运算速度。 使用方法 numba对代码进⾏加速时&#xff0c;给要优化的函数加上jit优化器即可。使⽤jit的时候可以让…

IDEA断点调试(debug)

目录 1.断点调试介绍 2.F8逐行执行代码 3.调试遇异常 4.调试时如何看源码 5.如何直接执行到下一个断点 F9 6.利用断点调试查看动态绑定机制 1.断点调试介绍 断点调试是指在程序的某一行设置一个断点&#xff0c;调试时&#xff0c;程序运行到这一 行就会停住&#xff0…

2023年国赛数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 算法介绍FP树表示法构建FP树实现代码 建模资料 ## 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#xff0c…

【Rust日报】2023-08-11 candle:一个极简的Rust机器学习框架

Bevys Third Birthday Bevy 是一个用 Rust 构建的令人耳目一新的数据驱动的游戏引擎&#xff0c;如果你想学习如何使用 Bevy 制作 2D/3D 游戏、可视化、用户界面或其他图形应用程序&#xff0c;那可以访问Bevy官网去了解更多。 阅读原文&#xff1a;https://bevyengine.org/new…

GPU Microarch 学习笔记 [1]

WARP GPU的线程从thread grid 到thread block&#xff0c;一个thread block在CUDA Core上执行时&#xff0c;会分成warp执行&#xff0c;warp的颗粒度是32个线程。比如一个thread block可能有1024个线程&#xff0c;分成32个warp执行。 上图的CTA&#xff08;cooperative thre…

西门子PLC模拟量接线及程序

接线 2线制接线 3线制接线 4线制接线 程序 指令 S_ITR 输入参数 EN 使能信号 AIW0 模拟量通道 ISH ISL 0-20ma对应 0-32000 4-20ma 对应 6400-32000 OSH OSL 传感器的测量值的最大和最小值 300 和 -50 输出参数 VD0 当前的测量温度

docker部署springboot

基础知识 什么是docker 官网&#xff1a; Docker Docs: How to build, share, and run applications | Docker Documentation Docker 是一个基于go语言开发的开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到…

Unity 鼠标实现对物体的移动、缩放、旋转

文章目录 1. 代码2. 测试场景 1. 代码 using UnityEngine;public class ObjectManipulation : MonoBehaviour {// 缩放比例限制public float MinScale 0.2f;public float MaxScale 3.0f;// 缩放速率private float scaleRate 1f;// 新尺寸private float newScale;// 射线pri…

简绘ChatGPT支持Midjourney绘图 支持stable diffusion绘图

简绘支持Midjourney绘图和stable diffusion绘图。 这意味着简绘具备Midjourney绘图和stable diffusion绘图功能的支持。

分支语句和循环语句(1)

这篇文章我们详细的把分支语句和循环语句给大家进行讲解。 分支语句&#xff1a; if switch 循环语句&#xff1a; while for do while goto语句&#xff1a; 1.什么是语句&#xff1f; C语句可分为以下五类&#xff1a; 1. 表达式语句 2. 函数调用语句 3. 控制…

k8s常用资源管理 控制

目录 Pod&#xff08;容器组&#xff09;&#xff1a;Pod是Kubernetes中最小的部署单元&#xff0c;可以包含一个或多个容器。Pod提供了一种逻辑上的封装&#xff0c;使得容器可以一起共享网络和存储资源 1、创建一个pod 2、pod管理 pod操作 目录 创建Pod会很慢 Pod&…

LLM as Co-integrator:重塑团队间交互,持续改进信息对齐

封面由 Microsoft Designer 生成 在五月份的 QCon 大会上&#xff0c;我们分享了《探索软件开发新工序&#xff1a;LLM 赋能研发效能提升》。在那次分享里&#xff0c;我们重点提及了团队并非所有的时间在 SDLC 上&#xff0c;可能只有 30%~50% 时间在开发软件上&#xff0c;甚…

Gitlab CI/CD笔记-第二天-主机套接字进行构建并push镜像。

一、安装gitlab-runner 1.可以是linux也可以是docker的 2.本文说的是docker安装部署的。 二、直接上.gitlab-ci.yml stages: # List of stages for jobs, and their order of execution - build-image build-image-job: stage: build-image image: harbor.com:543/docke…

一周开发问题回顾(2023年08月07日-2023年08月13日)

一周开发问题回顾2023年08月07日-2023年08月13日 1. Arrays.asList()与 new ArrayList()的区别1.1 Arrays1.1.1补充 ArrayList(Arrays.asList(array)) 1.2 ArrayList()1.2.1 创建ArrayList的几种方法 2.Mysql中group by的使用方式3.画图4. 时间倒排5. 工厂策略设计模式6.List注…

第三课-界面介绍SD-Stable Diffusion 教程

前言 我们已经安装好了SD&#xff0c;这篇文章不介绍难以理解的原理&#xff0c;说使用。以后再介绍原理。 我的想法是&#xff0c;先学会画&#xff0c;然后明白原理&#xff0c;再去提高技术。 我失败过&#xff0c;知道三天打鱼两天晒网的痛苦&#xff0c;和很多人一样试了…

<Vite>HMR实现原理

什么是HMR&#xff1f; HMR&#xff08;Hot Module Replacement&#xff09;是一种开发工具&#xff0c;也就是热更新。用于在应用程序运行时替换、添加或删除模块&#xff0c;而无需完全重新加载整个页面或重新启动应用程序。这可以极大地提高开发效率和调试体验。 HMR的优势 …

MyEverything项目测试

一、自动化测试用例 二、功能测试 测试环境&#xff1a;win10、IDEA 2020.3.3 2.1目录文件选择功能 测试步骤&#xff1a; 1、运行项目&#xff0c;点击"选择目录"按钮 2、选择目标文件夹 3、点击"选择文件夹按钮" 4、重复上面三个步骤一次 期望结…

【C语言】每日一题(错误的集合)

最近在牛客、力扣上做题&#xff0c;花费海量时间&#xff0c;苦不堪言&#xff0c;有时绞尽脑汁也想不出&#xff0c;痛定思痛&#xff0c;每日记录写的比较困难的题。 错误的集合 题目如上图所示 题主乍看之下觉得很简单&#xff0c;再看例子&#xff0c;不就是一个有序数组…

【npm run dev报错】无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。

1.winX键&#xff0c;使用管理员身份运行power shell 2.输入命令&#xff1a;set-executionpolicy remotesigned 3.输入”Y“,回车&#xff0c;问题解决。 文章来源&#xff1a;无法加载文件 C:\Program Files\nodejs\npm.ps1&#xff0c;因为在此系统上禁止运行脚本。 - 前…