› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
bransummer524
V2EX  ›  MySQL

MySQL 的一个问题

  •  
  •   bransummer524 · Jun 23, 2021 · 3444 views
    This topic created in 1929 days ago, the information mentioned may be changed or developed.

    这样一张表 table(primary-key id, unique-key a, b) 类似于 update table set b= 'foo' where a = 'bar' 这样的语句

    我同事说这样不行会导致锁表, 要改成 先 select id from table where a = 'bar' 然后再 update table set b= 'foo' where id = xx

    我无语,这..有必要?

    12 replies  •  2021-06-23 20:09:42 +08:00
    bransummer524
        1
    bransummer524  
    OP
       Jun 23, 2021
    RR 级别 , 唯一索引等值查询,明明就是行锁
    dongtingyue
        2
    dongtingyue  
       Jun 23, 2021
    半桶水晃荡,或者老古董。
    dongtingyue
        3
    dongtingyue  
       Jun 23, 2021
    不过还是有区别的,只有 a 的话锁的不止一个。
    Cy1
        4
    Cy1  
       Jun 23, 2021
    不会锁表吧,不是只会加 (a, b) 这棵索引树 全部 a 的间隙锁和行锁,以及 (id) 这棵主键索引树上对应 id 的行锁而已么
    zibber
        5
    zibber  
       Jun 23, 2021
    唯一索引如果 update 不指定 id, 如果在多个事务里操作不同行也会死锁,
    zibber
        6
    zibber  
       Jun 23, 2021
    我遇到过 组合唯一索引使用 a, b 条件去 update 多个事务操作不同行就会死锁, 并不是正常理解的行锁
    simonlu9
        7
    simonlu9  
       Jun 23, 2021
    有可能吧,索引上范围都会锁,但不一定会锁表
    BQsummer
        8
    BQsummer  
       Jun 23, 2021 via Android
    加了索引最差也是间隙锁,不会表锁
    sunnyday123
        9
    sunnyday123  
       Jun 23, 2021
    unique a,b 已经和 id 一一对应了,和 where id 的条件也没啥区别,next-key lock 锁的范围也不是有别吧
    sanestays
        10
    sanestays  
       Jun 23, 2021
    是会产生一个间隙锁的,有可能造成更新失败,可以自己试试,

    建表:
    CREATE TABLE `aaaa` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `a` varchar(255) DEFAULT NULL,
    `b` varchar(255) DEFAULT NULL,
    `c` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `un` (`a`,`b`) USING BTREE
    ) ENGINE=InnoDB ;

    数据:
    INSERT INTO `sane`.`aaaa`(`id`, `a`, `b`, `c`) VALUES (1, 'a', 'b', NULL);
    INSERT INTO `sane`.`aaaa`(`id`, `a`, `b`, `c`) VALUES (3, 'a', 'c', NULL);
    INSERT INTO `sane`.`aaaa`(`id`, `a`, `b`, `c`) VALUES (4, 'b', 'foo', NULL);
    INSERT INTO `sane`.`aaaa`(`id`, `a`, `b`, `c`) VALUES (5, 'c', 'b', NULL);

    更新语句:
    第一个:update aaaa set b= 'foo' where a = 'b';
    第二个:update aaaa set b= 'foo' where a = 'a';
    自己看下结果
    bransummer524
        11
    bransummer524  
    OP
       Jun 23, 2021
    @sanestays
    可能我描述的不是很清晰,让你误解了, 唯一键只有 a 字段, b 只是一个普通字段
    sanestays
        12
    sanestays  
       Jun 23, 2021
    @bransummer524 喔 我的问题 单个的话是会从 next-key lock 降级为 record key,和 where id 没有区别呀,没必要这样操作吧
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2209 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 06:03 · PVG 14:03 · LAX 23:03 · JFK 02:03
    ♥ Do have faith in what you're doing.