You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一INSERT语句多次EXPLAIN结果不同的原因排查

问题描述

正在使用EXPLAIN EXTENDED排查一条慢INSERT语句,发现多次执行同一查询的EXPLAIN EXTENDED返回结果不同,核心表现为possible_keys字段值不稳定——有时包含多个索引,有时仅单个,甚至为空,怀疑索引未被正确使用。

当前环境为测试服务器,无其他流量、定时任务及表结构变更。该问题在其他表也存在,生产与测试环境均出现,测试环境更频繁。

执行的INSERT语句

INSERT INTO `catalog_product_entity_varchar` (
  `attribute_id`,
  `store_id`,
  `value`,
  `row_id`
)
VALUES
  (
    '442',
    '0',
    'https://www.example.com/item/',
    '46242'
  )
  ON DUPLICATE KEY
  UPDATE
    `attribute_id` = VALUES(`attribute_id`),
    `store_id` = VALUES(`store_id`),
    `value` = VALUES(`value`),
    `row_id` = VALUES(`row_id`);

EXPLAIN查询语句

explain extended
INSERT INTO `catalog_product_entity_varchar` (
  `attribute_id`,
  `store_id`,
  `value`,
  `row_id`
)
VALUES
  (
    '442',
    '0',
    'https://www.sexample.com/item/',
    '46242'
  )
  ON DUPLICATE KEY
  UPDATE
    `attribute_id` = VALUES(`attribute_id`),
    `store_id` = VALUES(`store_id`),
    `value` = VALUES(`value`),
    `row_id` = VALUES(`row_id`);

版本信息

aurora_version           2.11.1                        
innodb_version           5.7.12                        
protocol_version         10                            
slave_type_conversions                                 
tls_version              TLSv1,TLSv1.1,TLSv1.2         
version                  5.7.12-log                    
version_comment          MySQL Community Server (GPL)  
version_compile_machine  x86_64                        
version_compile_os       Linux

表结构

CREATE TABLE `catalog_product_entity_varchar` (
  `value_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Value ID',
  `attribute_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute ID',
  `store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store ID',
  `value` varchar(255) DEFAULT NULL COMMENT 'Value',
  `row_id` int(10) unsigned NOT NULL COMMENT 'Version Id',
  PRIMARY KEY (`value_id`),
  UNIQUE KEY `CATALOG_PRODUCT_ENTITY_VARCHAR_ROW_ID_ATTRIBUTE_ID_STORE_ID` (`row_id`,`attribute_id`,`store_id`),
  KEY `CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID` (`attribute_id`),
  KEY `CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID` (`store_id`),
  CONSTRAINT `CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON DELETE CASCADE,
  CONSTRAINT `CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID` FOREIGN KEY (`attribute_id`) REFERENCES `eav_attribute` (`attribute_id`) ON DELETE CASCADE,
  CONSTRAINT `CAT_PRD_ENTT_VCHR_ROW_ID_CAT_PRD_ENTT_ROW_ID` FOREIGN KEY (`row_id`) REFERENCES `catalog_product_entity` (`row_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=567985353 DEFAULT CHARSET=utf8 COMMENT='Catalog Product Varchar Attribute Backend Table'

表行数:2,813,210行。


原因分析

多次执行EXPLAIN EXTENDED结果不同的核心原因如下:

  • 统计信息波动或不准确
    MySQL优化器依赖表的统计信息(如索引选择性、数据分布)生成执行计划。即使无主动数据变更,Aurora或MySQL后台可能异步刷新统计信息(比如自动执行ANALYZE TABLE的后台任务),或统计信息采样结果存在细微差异,导致优化器每次评估的候选索引集合不同,直接反映在possible_keys字段上。

  • ON DUPLICATE KEY语句的特殊性
    该语句本质是先尝试INSERT,再检查重复键以执行UPDATE。重复键检查阶段,所有包含唯一键/主键的索引、以及能快速定位重复行的普通索引,都可能被纳入候选范围。优化器会根据实时成本估算动态选择候选索引,导致possible_keys内容变化。

  • 优化器成本估算的细微波动
    即使统计信息整体稳定,MySQL优化器的成本计算模型会参考系统运行时状态(如缓存命中率、当前内存可用量),这些细微变化可能导致优化器对不同索引的成本评估出现偏差,进而改变possible_keys的输出。

  • MySQL 5.7版本的优化器特性
    你使用的MySQL 5.7.12版本,其优化器处理UPSERT语句时,索引候选选择逻辑本身存在一定灵活性,不像高版本MySQL那样稳定。加上Aurora 2.11.1基于该版本的定制化实现,进一步放大了执行计划的波动。


内容的提问来源于stack exchange,提问作者Ian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:32:17