当进行数据库操作时如果基于非主键字段进行删除,并且该字段没有索引,可能会导致InnoDB使用表级锁而不是行级锁

文章讨论了在MySQL中,不使用索引的删除操作可能导致表级锁,影响并发性能。通过为非索引字段添加索引,可实现行级锁,提高系统稳定性和效率。InnoDB的行锁依赖于索引,未命中索引会导致锁升级为表锁,影响其他事务执行。
摘要由CSDN通过智能技术生成

问题描述

 这种情况下,可能会影响其他事务的并发性能,从而降低系统的稳定性和效率。

举例来说,假设我们有一个名为setmeal_dish的表,其结构如下:

create table setmeal_dish
(
    id  bigint auto_increment comment '主键'
        primary key,
    setmeal_id bigint         null comment '套餐id',
    dish_id    bigint         null comment '菜品id',
    name       varchar(32)    null comment '菜品名称 (冗余字段)',
    price      decimal(10, 2) null comment '菜品单价(冗余字段)',
    copies     int            null comment '菜品份数'
)
    comment '套餐菜品关系' collate = utf8_bin;

现在,假设我们开启了两个事务事务1执行了删除操作,而事务2执行了更新操作。事务1的删除操作没有基于索引字段,而事务2的更新操作由于表级锁的缘故无法执行。

解决思路

通过为非索引字段添加索引,我们可以避免InnoDB使用表级锁,从而提高数据库的并发性能。这样,即使在删除操作时,也能保持数据库表的行级锁,确保其他事务可以正常执行,提高系统的稳定性和性能。


create index setmeal_dish_dish_id_index
    on setmeal_dish (dish_id);

再次测试

在添加索引后,再次进行相同的删除和更新操作

总结:没有命中索引的查询更新语句会加什么锁,跟命中索引的语句有什么不同?

简:InnoDB的行锁是实现在索引上的,而不是锁在物理行记录上。所以如果访问没有命中索引,就无法使用行锁,将要退化为表锁。

共享行锁上升为共享表锁,排他行锁上升为排他表锁。加表锁之前会检查意向排他锁来判断当前是否存在排他行锁,如果存在则需要阻塞等待排他行锁的释放,否则可以直接获得表锁。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值