mysql 联合表查询从表即使有索引依然ALL的一个原因-索引ALL解决,字符编码方式不一致导致全表搜索 mysql索引失效,是因为charset不一致导致 mysql索引 适用 字符类型一致

2024-10-09 10:55:55 浏览数 (1)

mysql 联合表查询从表即使有索引依然ALL的一个原因-索引ALL解决,字符编码方式不一致导致全表搜索 那就是主表和从表的关联字段的编码方式不一样!!!

mysql索引失效,是因为charset不一致导致 mysql索引 适用 字符类型一致

产生的现象:

解决之后,正确的使用了t2.order_no ref索引,而不是ALL

检查mysql主体编码方式,是否由于后来新建的表的关联字段和之前的主表的字段的编码方式不一样 改成一样的编码方式以后就ok了

#可以通过以下排查解决:

代码语言:javascript复制
#查看数据库编码格式
SHOW VARIABLES LIKE 'character_set_database';


#修改
#删除重新指定
CREATE DATABASE testDb CHARACTER SET utf8;
CREATE TABLE testTable(order_no VARCHAR(32) NOT NULL) DEFAULT CHARSET = utf8;

# 查看数据表的编码格式
SHOW CREATE TABLE testTable;
SHOW FULL COLUMNS FROM testTable;


#直接修改
#1、数据库修改
ALTER DATABASE testDb CHARACTER SET utf8;
#2、数据表修改
ALTER TABLE testTable CHARACTER SET utf8;  # UTF8MB3
ALTER TABLE testTable CHARACTER SET utf8mb4;

#3、表字段修改
ALTER TABLE testTable CHANGE order_no order_no VARCHAR(32) CHARACTER SET utf8 NOT NULL;
ALTER TABLE testTable CHANGE order_no order_no VARCHAR(32) CHARACTER SET utf8mb4 NOT NULL;

utf8_general_ci utf8mb4_general_ci MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。

SQL语句语法:如果没有正确的使用到索引,需要检查SQL语句是否正确,以下是DEMO:

简单介绍:order仅仅有order_no索引,multiple既有order_no索引,又有create_time索引

#t1仍然是ALL,因为where条件也跟它无关,且order是大表,主要查询业务的数据作为主表,其他的作为从表。

#t1是ALL索引 EXPLAIN SELECT * FROM `order` t1 use index (order_no) LEFT JOIN `multiple` t2 on t1.`order_no` =t2.`order_no` where t1.`create_time` >= '2023-06-01 00:00:00' and t1.`create_time` <= '2023-06-30 23:59:59';

#t1是ALL索引

EXPLAIN SELECT * FROM `order` t1 force index (order_no) LEFT JOIN `multiple` t2 on t1.`order_no` =t2.`order_no` where t1.`create_time` >= '2023-06-01 00:00:00' and t1.`create_time` <= '2023-06-30 23:59:59';

#t1是ref索引

EXPLAIN SELECT * FROM `order` t1 force index (order_no) LEFT JOIN `multiple` t2 on t1.`order_no` =t2.`order_no` where t2.`create_time` >= '2023-06-01 00:00:00' and t2.`create_time` <= '2023-06-30 23:59:59';

#t2是ref索引 EXPLAIN SELECT * FROM `multiple` t1 LEFT JOIN `order` t2 on t1.`order_no` =t2.`order_no` where t1.`create_time` >= '2023-06-01 00:00:00' and t1.`create_time` <= '2023-06-30 23:59:59';

0 人点赞