项目实战典型案例12——mysql数据库 数据类型与表字段类型不一致导致索引失效
创始人
2025-05-28 16:57:25
0次

mysql数据库 数据类型与表字段类型不一致导致索引失效

  • 一:背景介绍
  • 二:思路&方案
    • 数值类型
    • 日期和时间类型
    • 字符串类型
    • 二进制类型
    • 问题复现
    • 结论
  • 三、扩展
    • 索引列上有计算
    • 对索引使用函数
    • 对索引隐式类型转换
    • 其余索引失效的情况后续进行补充
  • 四:总结
  • 五:升华

一:背景介绍

mysql库中有两张表的查询速度特别慢,一张表是76015条数据,另一张表是217069条数据。推测使用由于数据类型与表字段类型不一致导致需要进行类型转换和索引失效导致查询速度慢的问题。
在这里插入图片描述
在这里插入图片描述

二:思路&方案

在进行思路和方案的制定之前,我们先学习一下mysql的数据类型。
MySQL的数据类型分为四种 数值型、字符型 日期和时间类型 二进制类型
数值型可以分为:整数类型浮点数类型

数值类型

类型说明大小(bytes)存储范围(无符号)存储范围(带符号)
TINYINT很小的整数10 〜255-128〜127
SMALLINT小的整数20〜65535-32768〜32767
MEDIUMINT中等大小的整数30〜16777215-8388608〜8388607
INT (INTEGHR普通大小的整数40〜4294967295-2147483648〜2147483647
BIGINT大整数80〜18446744073709551615-9223372036854775808〜9223372036854775807
FLOAT单精度浮点数40 和 1.175494351E-38~3.402823466E+38-3.402823466E+38~1.175494351E-38
DOUBLE双精度浮点数80,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)(-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)
DECIMAL (M, D),DEC压缩的“严格”定点数M+2

DECIMAL 的存储空间并不是固定的,而由精度值 M 决定,占用 M+2 个字节。

注意: 在 MySQL 中,定点数以字符串形式存储,在对精度要求比较高的时候(如货币、科学数据),使用 DECIMAL 的类型比较好,另外两个浮点数进行减法和比较运算时也容易出问题,所以在使用浮点数时需要注意,并尽量避免做浮点数比较。

日期和时间类型

类型说明大小(bytes)
YEAR年份值1
TIME时间值或持续时间3
DATE日期值3
DATETIME混合日期和时间值8
TIMESTAMP混合日期和时间值,时间戳4

字符串类型

类型说明大小(bytes)
CHAR(M)固定长度非二进制字符串M 字节,1<=M<=255
VARCHAR(M)变长非二进制字符串L+1字节,在此,L< = M和 1<=M<=255
TINYTEXT非常小的非二进制字符串L+1字节,在此,L<2^8
TEXT小的非二进制字符串L+2字节,在此,L<2^16
MEDIUMTEXT中等大小的非二进制字符串L+3字节,在此,L<2^24
LONGTEXT大的非二进制字符串L+4字节,在此,L<2^32
ENUM枚举类型,只能有一个枚举字符串值1或2个字节,取决于枚举值的数目 (最大值为65535)
SET一个设置,字符串对象可以有零个或 多个SET成员1、2、3、4或8个字节,取决于集合 成员的数量(最多64个成员)

注意:VARCHAR 和 TEXT 类型是变长类型,其存储需求取决于列值的实际长度(在前面的表格中用 L 表示),而不是取决于类型的最大可能尺寸。

例如,一个 VARCHAR(10) 列能保存一个最大长度为 10 个字符的字符串,实际的存储需要字符串的长度 L 加上一个字节以记录字符串的长度。对于字符 “abcd”,L 是 4,而存储要求 5 个字节。

二进制类型

类型说明大小(bytes)
BIT(M)位字段类型大约 (M+7)/8 字节
BINARY(M)固定长度二进制字符串M 字节
VARBINARY (M)可变长度二进制字符串M+1 字节
TINYBLOB (M)非常小的BLOB8
BLOB (M)小 BLOBL+2 字节,在此,L<2^16
MEDIUMBLOB (M)中等大小的BLOBL+3 字节,在此,L<2^24
LONGBLOB (M)非常大的BLOBL+4 字节,在此,L<2^32

问题复现

表索引
在这里插入图片描述
表字段类型
在这里插入图片描述
查询语句
使用数值类型进行查询

EXPLAINSELECT * FROM arpro_chapter_template WHEREis_delete	=0AND active_id=385538879022694400

结果
索引失效
会发现type类型变成了all全表查询,索引已经失效。
在这里插入图片描述
使用字符串类型查询

		EXPLAINSELECT * FROM arpro_chapter_template WHEREis_delete	='0'AND active_id=385538879022694400

结果
索引生效
在这里插入图片描述

结论

在进行数值类型转换时,会使我们的索引失效。补充:mysq在遇到字符串和数字比较的时候,会默认将字符串转换为数值类型进行处理,所以如果is_delete类型为数值类型,那么如果sql赋值给它的数据类型为字符串类型,那么索引是不会失效的。

我们在进行实体设计,包括给sql语句赋值的时候。最好是与数据库的数据类型保持以及,避免由于数据类型不一致的原因出现索引失效的情况。

三、扩展

总结索引失效的情况

索引列上有计算

执行sql如下:

		EXPLAINSELECT * FROM arpro_chapter_template WHEREis_delete+1=1

可以看出变成了全表扫描,索引列上有计算,索引会失效。因为索引里存储的是列的原始值而不是计算后的值。
在这里插入图片描述

对索引使用函数

在索引列上加某个函数,sql如下:

		EXPLAINSELECT * FROM arpro_chapter_template WHERESUM(is_delete)=1

编程全表扫描,索引失效。因为索引里存储的是列的原始值而不是计算后的值。
在这里插入图片描述

对索引隐式类型转换

1.如果索引字段是字符型,但是条件查询时,传入的是整型的话,会出现索引失效问题。
2.如果索引是整型,但是条件查询的时候,传入的是字符型,不会出现索引失效问题。
mysq在遇到字符串和数字比较的时候,会默认将字符串转换为数值类型进行处理,所以如果is_delete类型为数值类型,那么如果sql赋值给它的数据类型为字符串类型,那么索引是不会失效的。

上面的案例已经进行了实践,不再进行演示。

其余索引失效的情况后续进行补充

四:总结

1.与数据库打交道需要特别注意数据类型是否对应,不能忽视如何数据类型不一致会带来什么影响。
2.在开发过程中规避掉索引失效的情况,不使用索引与使用索引带来截然不同的效率。

五:升华

在总结博客的过程中,战胜了非理性,又在理性的阵营中加强了一步。
对于每一个案例都进行了实践和验证。

相关内容

热门资讯

终于懂了!微乐游戏小程序(透视... 终于懂了!微乐游戏小程序(透视器),微乐捉鸡麻将确实真的是有透视挂攻略该软件可以轻松地帮助玩家将微乐...
玩家必看!如何下载微乐自建房免... 玩家必看!如何下载微乐自建房免费黑科技(辅助器),微信微乐麻将切实存在有透视挂app1、首先打开如何...
盘点十款!微信小程序游戏辅助器... 盘点十款!微信小程序游戏辅助器(辅助器),微乐福州麻将一贯是真的有透视挂工具1、实时微信小程序游戏辅...
推荐十款!微信小程序微乐房间透... 推荐十款!微信小程序微乐房间透视(透视挂),微乐宁夏捉老麻子总是有透视挂软件;1、每一步都需要思考,...
今日头条!微信小程序多乐辅助器... 今日头条!微信小程序多乐辅助器(开挂),陕西微乐三代真是是有透视挂软件1、游戏颠覆性的策略玩法,独创...
推荐十款!微乐家乡小程序自建房... 推荐十款!微乐家乡小程序自建房辅助app(辅助),微乐自尊八喜一贯是有透视挂教程1、打开软件启动之后...
大家学习交流!微信小程序微乐破... 大家学习交流!微信小程序微乐破解器2024(作弊器),四川微乐麻将总是真的有透视挂app1、用户打开...
一起来探讨!微信卡五星小程序辅... 一起来探讨!微信卡五星小程序辅助(辅助),微乐捉鸡麻将竟然有透视挂方法1、许多玩家不知道微信卡五星小...
技术分享!微信小程序微乐破解填... 技术分享!微信小程序微乐破解填大坑(辅助器),微乐小程序微乐游戏好像有透视挂技巧1、技术分享!微信小...
实测发现!微乐自建房脚本如何下... 实测发现!微乐自建房脚本如何下载(作弊器),微乐锄大地果然有透视挂脚本1、每一步都需要思考,不同水平...