我有这张桌子:
CREATE TABLE `ClusterDescription` (
`ClusterDescriptionId` int(11) NOT NULL AUTO_INCREMENT,
`ClusterId` int(11) NOT NULL,
`RightBarDateTime` datetime NOT NULL,
`InstrumentId` int(11) NOT NULL,
`RowCreated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`ClusterDescriptionId`),
UNIQUE KEY `ClusterInstrumentId` (`ClusterId`,`InstrumentId`),
KEY `InstrumentId` (`InstrumentId`) USING BTREE,
KEY `OrderDesc` (`RightBarDateTime` DESC,`ClusterId` DESC)
) ENGINE=InnoDB AUTO_INCREMENT=3055989 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
该表有超过 3m 行。
我经常收到这个错误:
SQLSTATE[40001]:序列化失败:1213 尝试获取锁时发现死锁;尝试重启事务
对于这个命令:
INSERT INTO ClusterDescription (ClusterId, RightBarDateTime, InstrumentId)
SELECT IFNULL(MAX(ClusterId) + 1, 1), :rightBarDateTime, :instrumentId
FROM ClusterDescription WHERE InstrumentId = :instrumentId
- 几乎同时可以有多达 50 个以上的 INSERT。
:instrumentId
在任何并行命令中都不相同。- 检查进程列表,我看到许多这些命令等待执行的
Time
值 > 30 秒。 - 我设置
innodb_lock_wait_timeout
为 360 秒,这改善了这种情况。在我收到很多上述错误和这个错误之前:
SQLSTATE[HY000]:一般错误:1205 超过锁定等待超时;尝试重启事务
我的问题:
这个表定义有什么问题?
为什么需要执行超过 50 秒的并行 INSERT 命令?
为什么
dead lock
只有 1 个表受到影响时会收到错误消息?
在 MySQL 8.0.13 上运行
InnoDB
由于降序索引,我需要引擎。
这两者都提高了
SELECT MAX...
in the的效率INSERT..SELECT
:A计划
这假设您需要通过
ClusterId
.B计划
这涵盖了唯一性约束