Typical Project Case 12—Inconsistency between the data type of the mysql database and the type of the table field causes the index to fail

1: Background introduction

The query speed of two tables in the mysql database is extremely slow, one table has 76015 data, and the other table has 217069 data. It is speculated that due to the inconsistency between the data type and the table field type, type conversion is required and the index invalidation leads to slow query speed.
insert image description here
insert image description here

Two: ideas & solutions

Before formulating ideas and plans, let's learn about the data types of mysql.
MySQL's data types are divided into four types : numeric type, character type date and time type binary type
numeric type can be divided into: integer type floating point number type

value type

type illustrate size (bytes) memory range (unsigned) storage range (signed)
TINYINT very small integer 1 0 〜255 -128〜127
SMALLINT small integer 2 0〜65535 -32768〜32767
MEDIUMINT medium-sized integer 3 0〜16777215 -8388608〜8388607
INT (INTEGHR normal sized integer 4 0〜4294967295 -2147483648〜2147483647
BIGINT big integer 8 0〜18446744073709551615 -9223372036854775808〜9223372036854775807
FLOAT single precision floating point 4 0 and 1.175494351E-38~3.402823466E+38 -3.402823466E+38~1.175494351E-38
DOUBLE double precision floating point 8 0,(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 Compressed "strict" fixed-point numbers M+2

The storage space of DECIMAL is not fixed, but is determined by the precision value M, occupying M+2 bytes.

Note: In MySQL, fixed-point numbers are stored in the form of strings. When the accuracy requirements are relatively high (such as currency and scientific data), it is better to use the DECIMAL type. It is also easy to perform subtraction and comparison operations on the other two floating-point numbers. Something goes wrong, so you need to be careful when using floating-point numbers, and try to avoid doing floating-point comparisons.

date and time type

type illustrate size (bytes)
YEAR year value 1
TIME time value or duration 3
DATE date value 3
DATETIME Mixed date and time values 8
TIMESTAMP Mixed date and time values, timestamps 4

string type

type illustrate size (bytes)
CHAR(M) fixed-length non-binary string M bytes, 1<=M<=255
VARCHAR(M) variable-length non-binary string L+1 bytes, here, L<=M and 1<=M<=255
TINYTEXT very small non-binary string L+1 bytes, here, L<2^8
TEXT small non-binary string L+2 bytes, here, L<2^16
MEDIUMTEXT Medium-sized non-binary string L+3 bytes, here, L<2^24
LONGTEXT large non-binary string L+4 bytes, here, L<2^32
ENUM Enumeration type, can only have one enumeration string value 1 or 2 bytes, depending on the number of enumeration values ​​(maximum is 65535)
SET A SET, String object can have zero or more SET members 1, 2, 3, 4 or 8 bytes, depending on the number of set members (up to 64 members)

Note: VARCHAR and TEXT types are variable-length types, and their storage requirements depend on the actual length of the column value (indicated by L in the preceding table), not on the largest possible size of the type.

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

二进制类型

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

问题复现

表索引
insert image description here
表字段类型
insert image description here
查询语句
使用数值类型进行查询

EXPLAIN
		SELECT * FROM arpro_chapter_template 
		WHERE
			is_delete	=0
			AND 
			active_id=385538879022694400

结果
索引失效
会发现type类型变成了all全表查询,索引已经失效。
insert image description here
使用字符串类型查询

		EXPLAIN
		SELECT * FROM arpro_chapter_template 
		WHERE
			is_delete	='0'
			AND 
			active_id=385538879022694400
			

结果
索引生效
insert image description here

结论

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

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

三、扩展

总结索引失效的情况

索引列上有计算

执行sql如下:

		EXPLAIN
		SELECT * FROM arpro_chapter_template 
		WHERE
		is_delete+1=1
		

可以看出变成了全表扫描,索引列上有计算,索引会失效。因为索引里存储的是列的原始值而不是计算后的值。
insert image description here

对索引使用函数

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

		EXPLAIN
		SELECT * FROM arpro_chapter_template 
		WHERE
		SUM(is_delete)=1

Programming full table scan, index failure. Because the original value of the column is stored in the index instead of the calculated value.
insert image description here

Implicit type conversions for indexes

1. If the index field is a character type, but the integer type is passed in during the conditional query, the index failure problem will occur.
2. If the index is of integer type, but the character type is passed in during the conditional query, the problem of index failure will not occur.
When mysq encounters a comparison between a string and a number, it will convert the string to a numeric type by default, so if the type of is_delete is a numeric type, then if the data type assigned to it by SQL is a string type, then the index is not will fail.

The above cases have been practiced and will not be demonstrated.

If the rest of the indexes fail, they will be supplemented later

Four: Summary

1. When dealing with databases, you need to pay special attention to whether the data types correspond, and you cannot ignore the impact of inconsistencies in data types.
2. To avoid index failure during the development process, the efficiency of not using the index and using the index is completely different.

Five: Sublimation

In the process of summarizing the blog, I defeated the irrational and strengthened a step in the rational camp.
Practice and verification have been carried out for each case.

Guess you like

Origin blog.csdn.net/wangwei021933/article/details/129557554