MySQL无实际数据变更的UPDATE:是否修改索引或表数据?
关于UPDATE语句对表和索引影响的问题
测试用表结构
CREATE TABLE foobar ( col1 int not null, col2 int not null, col3 int not null, primary key (col1) ); CREATE INDEX myindex ON foobar (col2); INSERT INTO foobar(col1, col2, col3) VALUES(1, 99, 999);
场景1:仅设置与原值相同的列值
执行如下UPDATE语句:
UPDATE foobar SET col2=99 -- 与原值相同 WHERE col1=1;
问题:
- 是否会对索引结构产生任何修改(即使最终结构无变化)?
- 是否会修改表中的对应值(即使值未改变)?
解答:
在主流关系型数据库(如MySQL、PostgreSQL)中:
- 表数据:不会修改col2的存储值,数据库会先对比新旧值,确认完全一致后跳过该列的写入操作。
- 索引结构:不会对
myindex索引做任何修改,因为col2的值没有实际变化,无需触发索引项的删除或插入操作。
场景2:同时设置一个原值相同的列和一个新值的列
执行如下UPDATE语句:
UPDATE foobar SET col2=99 -- 与原值相同 , col3=444 -- 新值 WHERE col1=1;
问题:
此场景中col3被设为新值,但col2值未变,那么表中col2的值和col2对应的索引结构是否会被更新?
解答:
- 表中col2的值:不会被修改,数据库会对比col2的新旧值,确认无变化后跳过该列的写入流程。
- col2对应的索引结构:不会有任何更新操作,索引依赖的列值未发生实际变更,索引项无需调整。
优化建议
将更新语句改为仅设置实际变化的列(如下所示),确实能降低CPU和磁盘占用:
UPDATE foobar SET col3=444 -- 仅更新有变化的列 WHERE col1=1;
这种细粒度更新减少了数据库对未变更列的新旧值对比操作,也避免了不必要的列写入逻辑触发,降低了内部计算开销和磁盘IO消耗;在批量更新或高并发场景下,这种优化的效果会更显著。
内容的提问来源于stack exchange,提问作者Julio
相关产品推荐
相关产品推荐

