让【宝码香车】来帮你解答,本回答参考DeepSeek编写,并整理提供。
如果还有疑问可以点击头像关注私信或评论。如果答案让您满意,请采纳、点赞、关注,非常感谢!
MySQL外联查询不走索引问题分析
根据您提供的情况,这是一个典型的MySQL外联查询索引失效问题。我来分析原因并提供解决方案。
问题分析
您的查询语句:
SELECT
wm.id,
wus.`name` AS minSkuUnitName
FROM
wms_material wm
LEFT JOIN wms_unit wus ON wus.id = wm.min_sku_unit_id
WHERE
wm.del_flag = 0
索引失效的可能原因
- 数据类型不匹配:
wm.min_sku_unit_id和wus.id的数据类型不一致 - 索引选择性低:
min_sku_unit_id列的值分布不均匀或重复值过多 - 表大小差异:MySQL优化器认为全表扫描比使用索引更快
- 统计信息不准确:MySQL的统计信息没有及时更新
解决方案
1. 检查数据类型一致性
确保连接字段的数据类型完全一致:
-- 检查两表连接字段的数据类型
SHOW COLUMNS FROM wms_material LIKE 'min_sku_unit_id';
SHOW COLUMNS FROM wms_unit LIKE 'id';
2. 强制使用索引
可以尝试强制使用索引:
SELECT
wm.id,
wus.`name` AS minSkuUnitName
FROM
wms_material wm FORCE INDEX (index_name)
LEFT JOIN wms_unit wus FORCE INDEX (PRIMARY) ON wus.id = wm.min_sku_unit_id
WHERE
wm.del_flag = 0
3. 更新统计信息
ANALYZE TABLE wms_material;
ANALYZE TABLE wms_unit;
4. 使用EXPLAIN分析
EXPLAIN SELECT
wm.id,
wus.`name` AS minSkuUnitName
FROM
wms_material wm
LEFT JOIN wms_unit wus ON wus.id = wm.min_sku_unit_id
WHERE
wm.del_flag = 0;
为什么给wus.name加索引会走索引
当您给wus.name加索引后,MySQL优化器可能认为:
- 需要从
wus表获取name字段 - 通过索引获取
name比全表扫描更高效 - 因此选择了先通过主键关联,再通过索引获取
name
优化建议
- 确保连接字段数据类型一致
- 为
wm.min_sku_unit_id创建合适的索引 - 考虑使用复合索引(如果查询条件更多)
- 定期更新表统计信息
-- 创建索引示例
ALTER TABLE wms_material ADD INDEX idx_min_sku_unit_id (min_sku_unit_id);
希望这些分析能帮助您解决问题。如果仍有疑问,可以提供EXPLAIN的完整输出结果,我可以进一步分析。