MySQL 隐式转换与模糊匹配的索引使用分析

news2025/4/17 4:24:05

MySQL 隐式转换与模糊匹配的索引使用分析

  • MySQL服务版本
  • 字段结构
  • 索引结构
  • 查询分析
    • int索引查询
    • varchar 索引查询
  • like 匹配
  • 总结

MySQL服务版本

  • 版本信息:Server version: 8.0.30 MySQL Community Server - GPL

字段结构

mysql> desc connection;
+-----------------------+--------------+------+-----+---------+----------------+
| Field                 | Type         | Null | Key | Default | Extra          |
+-----------------------+--------------+------+-----+---------+----------------+
| id                    | int          | NO   | PRI | NULL    | auto_increment |
| type                  | int          | NO   |     | NULL    |                |
| name                  | varchar(50)  | NO   | MUL | NULL    |                |
| server_url_master     | text         | YES  |     | NULL    |                |
| prometheus_url_master | text         | YES  |     | NULL    |                |
| prometheus_url_slave  | text         | YES  |     | NULL    |                |
| username              | varchar(100) | NO   |     | NULL    |                |
| create_time           | timestamp    | YES  |     | NULL    |                |
| update_time           | timestamp    | YES  |     | NULL    |                |
| server_url_slave      | text         | YES  |     | NULL    |                |
+-----------------------+--------------+------+-----+---------+----------------+
10 rows in set (0.00 sec)

索引结构

为表 connection 添加了以下索引

alter table connection add index connection_name_index(name);
alter table connection add index connection_type_index(type)
  • 目前索引情况
mysql> SHOW INDEXES FROM connection;
+------------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table      | Non_unique | Key_name              | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+------------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| connection |          0 | PRIMARY               |            1 | id          | A         |           1 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| connection |          1 | connection_name_index |            1 | name        | A         |           1 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| connection |          1 | connection_type_index |            1 | type        | A         |           1 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+------------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.02 sec)

查询分析

int索引查询

  • int 索引 int 条件:
mysql> explain select type from connection where type = 1;
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys         | key                   | key_len | ref   | rows | filtered | Extra       |
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | connection | NULL       | ref  | connection_type_index | connection_type_index | 4       | const |    1 |   100.00 | Using index |
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

结果:type = 1 使用了索引,type字段的值是ref,表示直接通过索引定位到具体行,效率较高。
Extra:Using index,表示查询使用了覆盖索引,不需要回表查询表数据。

  • int 索引 string 条件:
mysql> explain select type from connection where type = '1';
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys         | key                   | key_len | ref   | rows | filtered | Extra       |
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | connection | NULL       | ref  | connection_type_index | connection_type_index | 4       | const |    1 |   100.00 | Using index |
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

结果:type = ‘1’ 同样使用了索引,type字段的值是ref,表示直接通过索引定位到具体行,效率较高。
Extra:Using index,表示查询使用了覆盖索引,不需要回表查询表数据。

varchar 索引查询

  • varchar 索引 int 条件:
mysql> explain select name from connection where name = 56;
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys         | key                   | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | connection | NULL       | index | connection_name_index | connection_name_index | 202     | NULL |    1 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
1 row in set, 3 warnings (0.00 sec)

结果:name = 56 使用了索引,但需要回表过滤。type字段的值是index,表示进行了索引扫描。
Extra:Using where; Using index,表示查询使用了索引,但需要通过WHERE子句过滤数据。

mysql> explain select name from connection where name = 56root;
ERROR 1054 (42S22): Unknown column '56root' in 'where clause'

结果:条件隐式转化失败,直接报错。
字段值无法转换为INT:如果STRING类型的字段中存在无法转换为INT的值(如包含非数字字符的字符串),在查询时MySQL会报错

  • varchar 索引 string 条件:
mysql> explain select name from connection where name = '56';
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys         | key                   | key_len | ref   | rows | filtered | Extra       |
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | connection | NULL       | ref  | connection_name_index | connection_name_index | 202     | const |    1 |   100.00 | Using index |
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

结果:name = ‘56’ 使用了索引,type字段的值是ref,表示直接通过索引定位到具体行,效率较高。
Extra:Using index,表示查询使用了覆盖索引,不需要回表查询表数据。

type 字段:表示查询的访问类型。常见的访问类型有 const、eq_ref、ref、range、index 和 all 等。
如果 type 字段为 const 或 eq_ref,则查询不需要回表。
如果 type 字段为 ref、range、index 或 all,则查询可能需要回表

like 匹配

  • MySQL使用索引直接定位到name = '56’的行。这是通过索引快速查找的方式,效率较高。
  • 使用了覆盖索引,不需要回表查询表数据。这意味着所有需要的字段(id和name)都在索引中,MySQL可以直接从索引中获取数据,而不需要访问表数据。
mysql> explain select id,name from connection where name like '56';
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys         | key                   | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | connection | NULL       | index | connection_name_index | connection_name_index | 202     | NULL |    1 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.01 sec)
  • MySQL使用了索引扫描。这意味着MySQL会扫描整个索引,而不是直接定位到具体的行。
mysql> explain select id,name from connection where name = '56';
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys         | key                   | key_len | ref   | rows | filtered | Extra       |
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | connection | NULL       | ref  | connection_name_index | connection_name_index | 202     | const |    1 |   100.00 | Using index |
+----+-------------+------------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
  • 最左匹配,范围查询,走索引,使用了索引条件推送 ICP技术,在存储引擎层直接评估索引条件,返回给服务器层,减少回表次数。
  • 使用索引进行范围查询 range,效率较高。
mysql> explain select id,name,type from connection where name like '56%';
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+-----------------------+
| id | select_type | table      | partitions | type  | possible_keys         | key                   | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | connection | NULL       | range | connection_name_index | connection_name_index | 202     | NULL |    5 |   100.00 | Using index condition |
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
  • 使用了索引扫描,无需回表
mysql> explain select id,name from connection where name like '56%';
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys         | key                   | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | connection | NULL       | index | connection_name_index | connection_name_index | 202     | NULL |    1 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+-------+-----------------------+-----------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.01 sec)
  • 不符合最左匹配,但仍然可以索引扫描,子句过滤。
  • MySQL仍然可以使用索引进行全索引扫描(index)。这意味着MySQL会扫描整个索引,而不是直接定位到具体的行。
  • 在这种情况下,索引扫描的效率比全表扫描(ALL)高,但仍然不如通过索引直接定位到具体行(如ref或range)高效。
mysql> explain select id,name from connection where name like '%6%';
+----+-------------+------------+------------+-------+---------------+-----------------------+---------+------+------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys | key                   | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+------------+------------+-------+---------------+-----------------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | connection | NULL       | index | NULL          | connection_name_index | 202     | NULL |    1 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+-------+---------------+-----------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
  • 不符合最左匹配,但仍然可以索引扫描,子句过滤。
mysql> explain select id,name from connection where name like '%root';
+----+-------------+------------+------------+-------+---------------+-----------------------+---------+------+------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys | key                   | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+------------+------------+-------+---------------+-----------------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | connection | NULL       | index | NULL          | connection_name_index | 202     | NULL |    1 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+-------+---------------+-----------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

总结

  • 隐式转换:
    • 索引字段类型为字符串时,加不加引号都可以走索引。
    • 索引字段类型为int时,如果不加引号且条件值无法隐式转换为int,会报错;否则会自动隐式转换。
  • 模糊匹配:
    • LIKE '56%' 符合最左匹配原则,可以利用索引进行范围查询,效率较高。
    • LIKE '%6%' 和 LIKE '%root' 不符合最左匹配原则,但仍然可以使用索引进行全索引扫描,效率不如直接定位到具体行(如 ref 或 range)高效。

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

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

相关文章

Python高阶函数-filter

1. 基本概念 filter() 是Python内置的高阶函数,用于过滤序列中的元素。它接收一个函数和一个可迭代对象作为参数,返回一个迭代器,包含使函数返回True的所有元素。 filter(function, iterable)2. 工作原理 惰性计算:filter对象是…

拍摄的婚庆视频有些DAT的视频文件打不开怎么办

3-12 现在的婚庆公司大多提供结婚的拍摄服务,或者有一些第三方公司做这方面业务,对于视频拍摄来说,有时候会遇到这样一种问题,就是拍摄下来的视频文件,然后会有一两个视频文件是损坏的,播放不了&#xff0…

图灵逆向——题一-动态数据采集

目录列表 过程分析代码实现 过程分析 第一题比较简单,直接抓包即可,没有任何反爬(好像头都不用加。。。) 代码实现 答案代码如下: """ -*- coding: utf-8 -*- File : .py author : 鲨鱼爱兜兜 T…

【新人系列】Golang 入门(十二):指针和结构体 - 上

✍ 个人博客:https://blog.csdn.net/Newin2020?typeblog 📝 专栏地址:https://blog.csdn.net/newin2020/category_12898955.html 📣 专栏定位:为 0 基础刚入门 Golang 的小伙伴提供详细的讲解,也欢迎大佬们…

Day20 -实例:红蓝队优秀集成式信息打点工具的配置使用

一、自动化-企业查询 ----ENScan 原理:集成企查查、爱企查、chinaz等,剑指hw/src。 1)首次使用先创建config文件 确认一下生成了 2)配置cookie 各个平台不一样,根据github作者的教程来【放入github收藏夹了】 我这…

MySQL学习笔记五

第七章数据过滤 7.1组合WHERE子句 7.1.1AND操作符 输入&#xff1a; SELECT first_name, last_name, salary FROM employees WHERE salary < 4800 AND department_id 60; 输出&#xff1a; 说明&#xff1a;MySQL允许使用多个WHERE子句&#xff0c;可以以AND子句或OR…

Python爬虫第5节-urllib的异常处理、链接解析及 Robots 协议分析

目录 一、处理异常 1.1 URLError 1.2 HTTPError 二、解析链接 2.1 urlparse() 2.2 urlunparse() 2.3 urlsplit() 2.4 urlunsplit() 2.5 urljoin() 2.6 urlencode() 2.7 parse_qs() 2.8 parse_qsl() 2.9 quote() 2.10 unquote() 三、分析网站Robots协议 3.1 R…

26届Java暑期实习面经,腾讯视频一面

短链接的生成原理 如何解决短链接生成的哈希冲突问题 如何加快从短链接到原链接的重定向过程 TCP 和 UDP 协议 如何理解 TCP 是面向连接的 为什么 TCP 的握手是 3 次 IO 模式 是否有真正写过一个底层的 Socket 通信 MySQL 的事务隔离级别 MVCC 机制 什么叫服务的并行 为什么能基…

Kafka负载均衡挑战解决

本文为 How We Solve Load Balancing Challenges in Apache Kafka 阅读笔记 kafka通过利用分区来在多个队列中分配消息来实现并行性。然而每条消息都有不同的处理负载&#xff0c;也具有不同的消费速率&#xff0c;这样就有可能负载不均衡&#xff0c;从而使得瓶颈、延迟问题和…

2025年第二期PMP考试中文报名时间定了!

近日&#xff0c;官方发布了《关于2025年6月15日PMI认证考试的报名通知》。根据通知&#xff0c;中国大陆地区2025年第二期PMI认证考试将于6月15日举行&#xff0c;中文报名将于4月17日正式开始。 一、报名安排 为缓解报名高峰期的网络拥堵&#xff0c;本次考试将采取分地区、…

LiT and Lean: Distilling Listwise Rerankers intoEncoder-Decoder Models

文章&#xff1a;ECIR 2025会议 一、动机 背景&#xff1a;利用LLMs强大的能力&#xff0c;将一个查询&#xff08;query&#xff09;和一组候选段落作为输入&#xff0c;整体考虑这些段落的相关性&#xff0c;并对它们进行排序。 先前的研究基础上进行扩展 [14,15]&#xff0c…

Ubuntu 服务器上运行相关命令,关闭终端就停止服务,怎么才能启动后在后台运行?

环境&#xff1a; Ubuntu 20.04 LTS 问题描述&#xff1a; Ubuntu 服务器上运行相关命令&#xff0c;关闭终端就停止服务&#xff0c;怎么才能启动后在后台运行&#xff1f; bash docker/entrypoint.sh解决方案&#xff1a; bash docker/entrypoint.sh 脚本在后台运行&…

前端工具方法整理

文章目录 1.在数组中找到匹配项&#xff0c;然后创建新对象2.对象转JSON字符串3.JSON字符串转JSON对象4.有个响应式对象&#xff0c;然后想清空所有属性5.判断参数不为空6.格式化字符串7.解析数组内容用逗号拼接 1.在数组中找到匹配项&#xff0c;然后创建新对象 const modifi…

关于Deepseek本地AI知识文档库被联网访问方法的探索

背景&#xff1a; 根据前面的文章&#xff0c;我们使用了anythingLLM搭建了本地知识库&#xff0c;这个虽然基本可以用了&#xff0c;但是你只能在anythingLLM的界面里面进行提问&#xff0c;自能自己用&#xff0c;那么能否让其他人也可以使用我们搭建的本地知识库呢根据我的…

一个简单的跨平台Python GUI自动化 AutoPy

象一下&#xff0c;你坐在电脑前&#xff0c;手指轻轻一点&#xff0c;鼠标自己动了起来&#xff0c;键盘仿佛被无形的手操控&#xff0c;屏幕上的任务自动完成——这一切不需要你费力&#xff0c;只靠几行代码就能实现。这就是AutoPy的魅力&#xff0c;一个简单却强大的跨平台…

【嵌入式系统设计师】知识点:第4章 嵌入式系统软件基础知识

提示:“软考通关秘籍” 专栏围绕软考展开,全面涵盖了如嵌入式系统设计师、数据库系统工程师、信息系统管理工程师等多个软考方向的知识点。从计算机体系结构、存储系统等基础知识,到程序语言概述、算法、数据库技术(包括关系数据库、非关系型数据库、SQL 语言、数据仓库等)…

基于RDK X3的“校史通“机器人:SLAM导航+智能交互,让校史馆活起来!

视频标题&#xff1a; 【校史馆の新晋顶流】RDK X3机器人&#xff1a;导览员看了直呼内卷 视频文案&#xff1a; 跑得贼稳团队用RDK X3整了个大活——给校史馆造了个"社牛"机器人&#xff01; 基于RDK X3开发板实现智能导航与语音交互SLAM技术让机器人自主避障不…

春芽儿智能跳绳:以创新技术引领运动健康新潮流

在全球运动健康产业蓬勃发展的浪潮中&#xff0c;智能健身器材正成为连接科技与生活的重要纽带。据《中国体育用品产业发展报告》显示&#xff0c;2023年中国智能运动装备市场规模突破千亿元&#xff0c;其中跳绳类目因兼具大众普及性与技术升级空间&#xff0c;年均增速超30%。…

NOA是什么?国内自动驾驶技术的现状是怎么样的?

国内自动驾驶技术的现状如何&#xff1f; 汽车的NOA指的是“Navigate on Autopilot”&#xff0c;即导航辅助驾驶或领航辅助驾驶。这是一种高级驾驶辅助系统&#xff08;ADAS&#xff09;的功能&#xff0c;它允许车辆在设定好起点和终点后&#xff0c;自动完成行驶、超车、变…

Linux 指令初探:开启终端世界的大门

前言 当我们初次接触 Linux&#xff0c;往往会被一串串在黑底屏幕中跳动的字符震撼甚至吓退。然而&#xff0c;正是这些看似晦涩的命令&#xff0c;构建了服务器、嵌入式系统乃至云计算的世界。 本篇将带你从最基础的 Linux 指令开始&#xff0c;逐步揭开命令行的神秘面纱。从…