我在我的小应用程序中遇到表锁定问题,想知道如何改进查询。
以下是相关的表格信息。
| assigned_presents | CREATE TABLE `assigned_presents` (
`id` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
`recipient_id` bigint(10) unsigned NOT NULL,
`present_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `recipient_id_index` (`recipient_id`),
KEY `present_id` (`present_id`),
CONSTRAINT `fk_message` FOREIGN KEY (`recipient_id`) REFERENCES `person` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=12914 DEFAULT CHARSET=latin1 |
| present | CREATE TABLE `present` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`description` varchar(100) DEFAULT NULL,
`type_id` int(10) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `present_type_id` (`present`,`type_id`),
KEY `index_type_id` (`type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=83196627 DEFAULT CHARSET=latin1 |
| person | CREATE TABLE `person` (
`id` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
KEY `added_index` (`added`),
) ENGINE=InnoDB AUTO_INCREMENT=249486846 DEFAULT CHARSET=utf8 |
这是我目前的查询。它完成了这项工作,但我想知道它是否可以改进。
INSERT INTO assigned_presents (present_id, recipient_id)
SELECT present.id, ${person_id} FROM present WHERE present.type_id IN (""" + ${present_type_options} + """)
AND NOT EXISTS (SELECT present_id FROM assigned_presents WHERE assigned_present.present_id=present.id)
ORDER BY present.id LIMIT 1
它基本上是为某个人(${present_type_options}
)分配特定类型(${person_id}
)的礼物,但确保尚未分配礼物。我希望这是有道理的。
我基本上只想在present_id
中插入person_id
和assigned_presents
,只要表格中不存在present_id
。
该查询对我有意义,但我不是一位经验丰富的MySQL用户。我确实看到在重负载下调用时可能存在行锁定问题(我还没弄清楚如何对其进行压力测试),因为查询在插入之前依赖于两个选择查询。
我得到的错误是:
Deadlock found when trying to get lock; try restarting transaction
另外,我无法重试查询。它第一次被调用时就可以工作了。这样做的原因是,这是第一个服务类型API中的第一个,其中响应是立即的。
希望有人可以提供帮助。