La inconsistencia entre el tipo de datos de la base de datos mysql y el tipo de 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.
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 |
问题复现
表索引
表字段类型
查询语句
使用数值类型进行查询
EXPLAIN
SELECT * FROM arpro_chapter_template
WHERE
is_delete =0
AND
active_id=385538879022694400
结果
索引失效
会发现type类型变成了all全表查询,索引已经失效。
使用字符串类型查询
EXPLAIN
SELECT * FROM arpro_chapter_template
WHERE
is_delete ='0'
AND
active_id=385538879022694400
结果
索引生效
结论
在进行数值类型转换时,会使我们的索引失效。补充:mysq在遇到字符串和数字比较的时候,会默认将字符串转换为数值类型进行处理,所以如果is_delete类型为数值类型,那么如果sql赋值给它的数据类型为字符串类型,那么索引是不会失效的。
我们在进行实体设计,包括给sql语句赋值的时候。最好是与数据库的数据类型保持以及,避免由于数据类型不一致的原因出现索引失效的情况。
三、扩展
总结索引失效的情况
索引列上有计算
执行sql如下:
EXPLAIN
SELECT * FROM arpro_chapter_template
WHERE
is_delete+1=1
可以看出变成了全表扫描,索引列上有计算,索引会失效。因为索引里存储的是列的原始值而不是计算后的值。
对索引使用函数
在索引列上加某个函数,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.
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.