MySql数据类型都是字符串(varchar),数据类型一样,但是联表查询不走索引,是什么原因呢

news2024/11/10 20:43:25

大家都知道,如果联表查询中,数据类型不一样,是很有可能不走索引的,但是有时候数据类型一样也是有可能不走索引的,我们往下看

1 数据准备

我们准备两个表,用来模拟联表查询

1.1 user表

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `phone` varchar(20) DEFAULT NULL COMMENT '手机号码',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_phone` (`phone`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
INSERT INTO `user` (`id`, `phone`) VALUES (1, '13836038931');
INSERT INTO `user` (`id`, `phone`) VALUES (2, '13836038932');

1.2 user_info表

CREATE TABLE `user_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `phone` varchar(50) CHARACTER SET utf8 NOT NULL,
  `sex` int(11) NOT NULL COMMENT '性别(0:女,1:男)',
  `intro` text NOT NULL COMMENT '简介',
  PRIMARY KEY (`id`),
  KEY `index_phone` (`phone`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
INSERT INTO `user_info` (`id`, `phone`, `sex`, `intro`) VALUES (1, '13836038931', 1, '简介');
INSERT INTO `user_info` (`id`, `phone`, `sex`, `intro`) VALUES (2, '13836038932', 0, '简介');
INSERT INTO `user_info` (`id`, `phone`, `sex`, `intro`) VALUES (3, '110', 1, '警察');
INSERT INTO `user_info` (`id`, `phone`, `sex`, `intro`) VALUES (4, '120', 1, '消防员');
INSERT INTO `user_info` (`id`, `phone`, `sex`, `intro`) VALUES (5, '119', 1, '医生');

2 情景再现

请看上述两个表的表结构,两个表的phone字段的字段类型都是varchar(50),但是字符集是不一样的,一个是utf8mb4,一个是utf8,所以我们执行一下SQL:

select u.phone, ui.sex, ui.intro
from user u 
inner join user_info ui on u.phone = ui.phone;

执行结果:

执行结果没问题,我们看下是否走了索引

由此可见索引没走了,走全表了,造成这种情况无外乎两种原因:

第一种sql数据太少,sql优化器认为走全表更快,不走索引

第二种就是两个字段虽然数据类型一样,但是字符集不一样,所以索引没走

我们把user_info表的字符集做一下修改:

ALTER TABLE `user_info` 
MODIFY COLUMN `phone` varchar(50) CHARACTER SET utf8mb4 NOT NULL AFTER `id`;

再执行上面的sql,查看执行计划:

可以看出索引走了

3 为何字符集不一样,会不走索引

在MySQL中,当字符集不同的字段进行联表查询时,会导致索引失效,从而无法利用索引加速查询。

这是因为MySQL在进行查询时,会将查询条件中的字符串转换为索引字段的字符集,然后再进行匹配。如果字符集不同,MySQL需要将查询条件字符串转换为索引字段字符集,这将导致索引失效。

例如,假设有两个表A和B,其中A表中的字段使用utf8mb4字符集,而B表中的字段使用gbk字符集。如果在这两个表中进行联表查询,且查询条件包含A表中的字段和B表中的字段,那么MySQL将需要将这两个字段的字符集进行转换才能进行匹配,而这将导致索引失效,从而无法利用索引进行查询。这种情况我们在上面已经经过演示了。

为了避免这种情况,可以在设计表结构时尽量统一使用同一种字符集,或者在创建索引时指定字符集。此外,还可以通过在查询语句中使用转换函数来将字符集转换为索引所在的字符集,从而使得索引得以正确匹配,从而提高查询效率。

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

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

相关文章

华为OD机试用Python实现 -【几何平均值最大子数组】| 2023年3月被抽中

华为OD机试题 最近更新的博客华为 OD 机试 300 题大纲几何平均值最大子数组题目描述输入描述输出描述说明示例一输入输出说明示例二输入输出说明Python 代码实现核心逻辑最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单</

测试只能干到35岁?35岁+的测试就会失业?

互联网行业在很多年轻人的眼中&#xff0c;是高薪的象征。前几年的软件测试行业还是一个风口&#xff0c;随着不断地转行人员以及毕业的大学生疯狂地涌入软件测试行业&#xff0c;但是现在裁员潮涌现的时候&#xff0c;互联网行业首当其冲&#xff0c;互联网企业大量的裁员&…

当你开始学习 Python 时,这是一个简单的学习计划及当你初学 Python 时,这里有几个建议

当你开始学习 Python 时&#xff0c;这是一个简单的学习计划&#xff1a; 1.入门 安装Python环境并熟悉基本的Python语法 熟悉Python的基本数据类型&#xff0c;例如数字、字符串和列表 学习控制流程&#xff0c;例如条件语句和循环语句 掌握函数和模块的基本知识 2.进阶 …

Qt开发基本步骤示例:输入半径显示圆的面积

目录 1. 创建一个新项目 1.1 创建类的基类 1.2 main.cpp代码释义 2. 代码写在哪&#xff1f; 2.1 怎么找到我们需要的函数&#xff1f; 1. 创建一个新项目 点击创建项目&#xff0c;开始创建&#xff1a; 1.1 创建类的基类 QMainWindow&#xff1a;带菜单栏的窗口QWidge…

第一章——冯·诺伊曼结构计算机工作原理及层次结构分析

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;计算机组成原理 …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 目录第一章——冯诺伊曼结构计算…

深入浅出RPC框架-学习笔记

1 基本概念 1.1 本地函数调用 1.2 远程函数调用 1.3 RPC概念模型 5个模型组成&#xff1a;User、User-Stub、RPC-Runtime、Server-Stub、Server 1.4 一次RPC的完整过程 1.4.1 IDL (Interface description language)文件 IDL通过一种中立的方式来描述接口&#xff0c;使得在不…

JavaScript(1)

JavaScript简介 JavaScript是一门跨平台、面向对象的脚本语言&#xff0c;用来控制网页行为的&#xff0c;它能使网页可以交互。 JavaScript引入方式 1、内部脚本 将js代码定义在HTML页面中&#xff0c;在HTML中&#xff0c;JavaScript代码必须位于<script>与</scrip…

用C语言写一个自己的shell-Part Ⅱ--execute commands

Part Ⅱ–execute commands Exec This brings us to the exec family of functions. Namely, it has the following functions: execlexecvexecleexecveexeclpexecvp For our needs,we will use execvp whose signature looks like this int execvp(const char *file, cha…

【数据库专题】数据库Mongodb之深入认知云计算三种服务方式、mongodb特点、mongodb重要进程 mongod、mongo、其他进程区别

文章目录一、什么是云计算1. IaaS:基础设施即服务2. SaaS:软件即服务3. PaaS:平台即服务二、大数据与云计算关系三、什么是MongoDB四、大数据与MongoDB五、MongoDB特点六、安装MongoDB七、重要进程介绍7.1 mongod进程7.2 mongo进程7.3 其他进程7.3.1 mongodump重建数据库7.3.2 …

解决封号 Walmart最全申诉步骤

最近龙哥听说不少平台的账号都被封掉&#xff0c;登不上去了。所以龙哥赶紧就把这篇Walmart申诉教程提上日程&#xff0c;以防这个不时之需哈。当时Walmart的这个封号申诉规则和社交平台的还是有很大区别的&#xff0c;今天龙哥就从封号原因和申诉流程两方面展开&#xff0c;让…

210 裸机程序烧录

一、驱动安装 1.1 dnw驱动安装 禁用win10驱动程序强制签名 设置 -> 更新和安全 -> 恢复 -> 立即重启 -> 疑难解答 -> 高级选项 -> 启动设置 -> 重启 -> 按提示输入“F7”硬件设备正常上电工作&#xff0c;插入USB线连接电脑&#xff0c;设备管理器识…

源表测试软件下载安装教程

软件&#xff1a;源表测试软件NS-SourceMeter 语言&#xff1a;简体中文 环境&#xff1a;NI-VISA 安装环境&#xff1a;Win10以上版本&#xff08;特殊需求请后台私信联系客服&#xff09; 硬件要求&#xff1a;CPU2GHz 内存4G(或更高&#xff09;硬盘500G(或更高&#xf…

BGP之BGP联邦综合实验

目录 BGP联邦综合实验 实验图 网段划分 基础配置 路由配置 启动AS2中的ospf--- IGP协议 检测IGP 启动AS之间的BGP 测试 发布R1路由 修改&#xff1a;下一跳解决上述问题 解决水平分割 发布R8路由 测试 AS2内部环回路由信息互相访问 配置空接口 发布静态路由 测试…

经典蓝牙Sniff Mode

文章目录IntroductionApplicationSniff Sub-ratingReferenceIntroduction Sniff mode为两个已连接的经典蓝牙设备提供了有效的降低功耗的方法。我们知道&#xff0c;当没有数据需要传输的时候&#xff0c;两个已连接的蓝牙设备之间也需要每两个slots完成一次POLL packet - NUL…

系列九、视图/存储过程/存储函数/触发器

一、视图 1.1、概述 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&#xff0c;视图只保存了查询的SQL逻辑&#xff0c;…

pb插入ole控件点击insert+control时自动关闭解决办法

pb插入ole控件点击insert control时pb应用程序自动关闭解决思路 {F2F7F2A6-E582-11D1-89AC-00C04FCAF6E3} {F515306D-0156-11d2-81EA-0000F87557DB} 1、问题现象:当在powerbuilder中插入OLE控件点击insert control时,应用程序自动关闭,如图 在网上查询时有人说是其他…

深度剖析:伊朗钢铁厂入侵路径推测及对钢企数字化安全转型启示

2022年6月27日&#xff0c;名为Gonjeshke Darande的黑客组织声称对隶属于伊朗革命卫队&#xff08;IRGC&#xff09;和伊朗巴斯杰民兵组织&#xff08;Basij&#xff09;的Khouzestan、Mobarakeh、Hormozgan三家钢铁公司开展了网络攻击&#xff0c;致使Khouzestan钢铁厂一台重型…

【论文阅读】Attributed Graph Clustering with Dual Redundancy Reduction(AGC-DRR)

【论文阅读】Attributed Graph Clustering with Dual Redundancy Reduction&#xff08;AGC-DRR&#xff09; 文章目录【论文阅读】Attributed Graph Clustering with Dual Redundancy Reduction&#xff08;AGC-DRR&#xff09;1. 来源2. 动机3. 模型框架4. 方法介绍4.1 基本符…

Linux端口开通

Linux端口开开启有两种方式 firewall方式&#xff08;centos7.*&#xff09;修改iptables&#xff08;centos6.*&#xff09; 一、firewall方式 查看防火墙状态firewall-cmd --state如果返回的是 “not running”&#xff0c;那么需要先开启防火墙&#xff1b; 开启防火墙sy…

Java02 变量和运算符

Java02 变量和运算符 2.1 Java代码的基本格式 //类的定义 修饰符 class 类名{public static void main(String[] args){// 代码System.out.println("Hello World&#xff01;");} }现阶段&#xff0c;可以将一个类理解成Java程序&#xff08;.java文件&#xff09;…