Caso de proyecto típico 12: la inconsistencia entre el tipo de datos de la base de datos mysql y el tipo del campo de la tabla hace que el índice falle

1: Introducción de fondo

La velocidad de consulta de dos tablas en la base de datos mysql es extremadamente lenta. Una tabla tiene datos 76015 y la otra tabla tiene datos 217069. Se especula que debido a la inconsistencia entre el tipo de datos y el tipo de campo de la tabla, se requiere la conversión de tipo y la invalidación del índice conduce a una velocidad de consulta lenta.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Dos: ideas y soluciones

Antes de formular ideas y planes, aprendamos sobre los tipos de datos de mysql.
Los tipos de datos de MySQL se dividen en cuatro tipos : tipo numérico, tipo de carácter , tipo de fecha y hora, tipo binario
, tipo numérico que se puede dividir en: tipo entero, punto flotante, tipo numérico

tipo de valor

tipo ilustrar tamaño (bytes) rango de memoria (sin firmar) rango de almacenamiento (firmado)
TINYINT entero muy pequeño 1 0 〜255 -128〜127
PEQUEÑO entero pequeño 2 0〜65535 -32768〜32767
MENTA MEDIO entero de tamaño mediano 3 0〜16777215 -8388608〜8388607
INT (ENTERO entero de tamaño normal 4 0〜4294967295 -2147483648〜2147483647
EMPEZANDO entero grande 8 0〜18446744073709551615 -9223372036854775808〜9223372036854775807
FLOTAR punto flotante de precisión simple 4 0 y 1,175494351E-38~3,402823466E+38 -3.402823466E+38~1.175494351E-38
DOBLE punto flotante de precisión doble 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 308 7 E+ 315)
DECIMAL (M, D),DEC Números de punto fijo "estrictos" comprimidos M+2

El espacio de almacenamiento de DECIMAL no es fijo, sino que está determinado por el valor de precisión M, ocupando M+2 bytes.

Nota: En MySQL, los números de punto fijo se almacenan en forma de cadenas. Cuando los requisitos de precisión son relativamente altos (como moneda y datos científicos), es mejor usar el tipo DECIMAL. También es fácil realizar restas y operaciones de comparación en los otros dos números de punto flotante Algo sale mal, por lo que debe tener cuidado al usar números de punto flotante y tratar de evitar hacer comparaciones de punto flotante.

tipo de fecha y hora

tipo ilustrar tamaño (bytes)
AÑO valor del año 1
TIEMPO valor de tiempo o duración 3
FECHA valor de fecha 3
FECHA Y HORA Valores mixtos de fecha y hora 8
MARCA DE TIEMPO Valores mixtos de fecha y hora, marcas de tiempo 4

tipo de cadena

tipo ilustrar tamaño (bytes)
ENCANTO) cadena no binaria de longitud fija M bytes, 1<=M<=255
VARCHAR(M) cadena no binaria de longitud variable L+1 bytes, aquí, L<=M y 1<=M<=255
TEXTO PEQUEÑO cadena no binaria muy pequeña L+1 bytes, aquí, L<2^8
TEXTO pequeña cadena no binaria L+2 bytes, aquí, L<2^16
TEXTO MEDIO Cadena no binaria de tamaño mediano L+3 bytes, aquí, L<2^24
TEXTO LARGO gran cadena no binaria L+4 bytes, aquí, L<2^32
ENUM Tipo de enumeración, solo puede tener un valor de cadena de enumeración 1 o 2 bytes, dependiendo del número de valores de enumeración (el máximo es 65535)
COLOCAR Un objeto SET, String puede tener cero o más miembros SET 1, 2, 3, 4 u 8 bytes, según el número de miembros del conjunto (hasta 64 miembros)

Nota: los tipos VARCHAR y TEXT son tipos de longitud variable y sus requisitos de almacenamiento dependen de la longitud real del valor de la columna (indicado por L en la tabla anterior), no del tamaño más grande posible del tipo.

例如,一个 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

问题复现

表索引
inserte la descripción de la imagen aquí
表字段类型
inserte la descripción de la imagen aquí
查询语句
使用数值类型进行查询

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

结果
索引失效
会发现type类型变成了all全表查询,索引已经失效。
inserte la descripción de la imagen aquí
使用字符串类型查询

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

结果
索引生效
inserte la descripción de la imagen aquí

结论

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

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

三、扩展

总结索引失效的情况

索引列上有计算

执行sql如下:

		EXPLAIN
		SELECT * FROM arpro_chapter_template 
		WHERE
		is_delete+1=1
		

可以看出变成了全表扫描,索引列上有计算,索引会失效。因为索引里存储的是列的原始值而不是计算后的值。
inserte la descripción de la imagen aquí

对索引使用函数

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

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

Programación de escaneo de tabla completa, falla de índice. Porque el valor original de la columna se almacena en el índice en lugar del valor calculado.
inserte la descripción de la imagen aquí

Conversiones de tipo implícitas para índices

1. Si el campo de índice es un tipo de carácter, pero se pasa el tipo entero durante la consulta condicional, se producirá el problema de error de índice.
2. Si el índice es de tipo entero, pero el tipo de carácter se pasa durante la consulta condicional, no se producirá el problema de la falla del índice.
Cuando mysq encuentra una comparación entre una cadena y un número, convertirá la cadena a un tipo numérico de forma predeterminada, por lo que si el tipo de is_delete es un tipo numérico, si el tipo de datos que le asigna SQL es un tipo de cadena, entonces el índice no fallará.

Los casos anteriores han sido practicados y no serán demostrados.

Si el resto de índices fallan, se complementarán más adelante.

Cuatro: Resumen

1. Cuando trabaje con bases de datos, debe prestar especial atención a si los tipos de datos se corresponden y no puede ignorar el impacto de las inconsistencias en los tipos de datos.
2. Para evitar fallas en el índice durante el proceso de desarrollo, la eficiencia de no usar el índice y usar el índice es completamente diferente.

Cinco: sublimación

En el proceso de resumir el blog, derroté lo irracional y fortalecí un paso en el campo racional.
Se han realizado prácticas y comprobaciones para cada caso.

Supongo que te gusta

Origin blog.csdn.net/wangwei021933/article/details/129557554
Recomendado
Clasificación