mysql left join关联字段的类型不一致导致索引失效

14 篇文章 2 订阅

有如下两张表:

CREATE TABLE `order`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `order_id` int NULL DEFAULT NULL COMMENT '订单ID',
  `order_amount` int NULL DEFAULT NULL COMMENT '订单金额',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `order_index_order_id`(`order_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单' ROW_FORMAT = DYNAMIC;

CREATE TABLE `order_detail`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `order_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单ID',
  `goods` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '商品名称',
  `goods_count` int NOT NULL COMMENT '商品数量',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `order_detail_index_order_id`(`order_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单明细' ROW_FORMAT = DYNAMIC;

看下这条sql的explain

EXPLAIN
SELECT
	t1.order_id, t1.order_amount, t2.goods, t2.goods_count 
FROM
	`order` t1
LEFT JOIN `order_detail` t2 ON t2.order_id = t1.order_id;

在这里插入图片描述

t1和t2通过order_id关联,order_id在t2建有索引order_detail_index_order_id,
但是这里却没有用到。

原因是order_id字段在t1中是int类型,在t2中是varchar类型,导致用不到索引。

一种办法是修改字段类型让它们保持一致,
不过修改字段类型有时候会可能遇到一些阻碍。

我们用另外一种办法,在查询中通过函数将它们转换为一样的类型和字符集。

EXPLAIN
SELECT
	t1.order_id, t1.order_amount, t2.goods, t2.goods_count 
FROM
	`order` t1
LEFT JOIN `order_detail` t2 ON t2.order_id = CONVERT ( CONVERT ( t1.order_id, CHAR ) USING utf8 );

在这里插入图片描述
这下索引生效了。

可能会有人不清楚为什么用到了t2的索引,可以看下这个:MySQL join查询的原理

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值