先贴出建表语句
CREATE TABLE `demo_table` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL DEFAULT '0',
  `status` tinyint(1) NOT NULL DEFAULT '0',
  `reward` int(11) NOT NULL DEFAULT '0',
  `rules` varchar(255) NOT NULL DEFAULT '',
  `created_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `sign_time` datetime DEFAULT NULL,
  `replenish_time` datetime DEFAULT NULL,  PRIMARY KEY (`id`),
  UNIQUE KEY `user_created_time` (`user_id`,`created_time`) USING HASH,
  UNIQUE KEY `user_sign_time` (`user_id`,`sign_time`) USING BTREE,
  KEY `user_id` (`user_id`) USING HASH,
  KEY `created_time` (`created_time`) USING BTREE,
  KEY `status` (`status`) USING BTREE,
  KEY `status_created_time` (`status`,`created_time`) USING BTREE,
  KEY `sign_time` (`sign_time`) USING BTREE,
  KEY `status_replenish_time` (`status`,`replenish_time`) USING BTREE,
  KEY `replenish_time` (`replenish_time`) USING BTREE,
  KEY `user_replenish_time` (`user_id`,`replenish_time`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=66681184 DEFAULT CHARSET=utf8表的数据量达到
查询语句分析:explain DELETE FROM `demo_table` WHERE `user_id` = 884308 AND `sign_time` <= '2018-04-20 09:36:51' AND `status` = 0
结果显示只使用了status字段,预期至少应该使用user_id字段才符合我的想法,但可能由于通过status索引来扫描的原因,导致锁了许多记录,把别的用户status=0也给锁住了,别的用户在别的请求里进行update时就报错我想过强制声明使用user_id索引来解决,但还是希望先找出原因,通过调整条件的方式来防止对其他用户记录的锁定,不知道为什么会决定使用了status,是不是我非要声明FORCE INDEX?表结构短时间内是不方便调整的了~

解决方案 »

  1.   

    把status字段索引删掉
      

  2.   

    其实还有许多字段没贴出来,但那些字段没加索引。不过才醒起status不应该加索引啊,它的值只有6种。现在表已经有5千万条记录了,希望删除索引时不会锁太久吧
      

  3.   

    另外为什么会决定使用status的呀,我想知道原因
      

  4.   

      KEY `user_id` (`user_id`) USING HASH,
    改成 BTREE 试试