Mysql : 更新主键和额外位置的性能,会不会更慢?
Mysql : performance of update with primary key and extra wheres, will it be slower?
假设我有一个 table 如下
CREATE TABLE `Foo` (
`id` int(10) unsigned NOT NULL,
`bar1` int(10) unsigned NOT NULL,
`bar2` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
);
我有两个问题:
update Foo set bar1=10 where id=5000;
update Foo set bar1=10 where id=5000 and bar1=0;
我的猜测是第二个查询不会 运行 比第一个查询慢,但我需要有一定知识的人的确认。
(我之所以要做第二个是因为当多个客户端select先table然后同时更新时只有一个人能够更新成功)
- 找到该行。优化器将查看可能的索引(仅 PK)并决定从
id=5000
开始。最多只有一行。
- (针对第二种情况)验证
bar1=0
。如果不是,则查询结束。
- 检查是否有任何需要更改的内容 --
bar1
是否已设置为 10?如果是,完成。
- 执行更新工作——这涉及在
ROLLBACK
的情况下保存现有行,暂时存储新值,等等——这一步可能是成本最高的一步.
第 2 步是唯一的区别 -- 这是一个非常小的步骤。在性能方面不值得担心。
另一方面,第 2 步意味着这两个更新是不同的 -- 如果 bar1=4567
会发生什么?第一次更新会改变它,但第二次不会。
您的最后评论暗示也许您应该使用交易来防止一个客户踩到另一个客户。也许代码应该更像:
BEGIN;
SELECT ... WHERE id = 5000 FOR UPDATE;
decide what to do -- which might include ROLLBACK and exit
UPDATE Foo SET bar1=10 WHERE id = 5000;
COMMIT;
底线:使用事务而不是额外的代码来处理并发。
警告:交易应该“快”(少于几秒)。如果您需要一个“长”事务(例如,可能需要几分钟才能完成的 'shopping cart'),则需要一种不同的机制。如果您需要长期交易,请开始一个新问题来解释情况。 (当前问题是讨论单个Update的性能。)
假设我有一个 table 如下
CREATE TABLE `Foo` (
`id` int(10) unsigned NOT NULL,
`bar1` int(10) unsigned NOT NULL,
`bar2` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
);
我有两个问题:
update Foo set bar1=10 where id=5000;
update Foo set bar1=10 where id=5000 and bar1=0;
我的猜测是第二个查询不会 运行 比第一个查询慢,但我需要有一定知识的人的确认。
(我之所以要做第二个是因为当多个客户端select先table然后同时更新时只有一个人能够更新成功)
- 找到该行。优化器将查看可能的索引(仅 PK)并决定从
id=5000
开始。最多只有一行。 - (针对第二种情况)验证
bar1=0
。如果不是,则查询结束。 - 检查是否有任何需要更改的内容 --
bar1
是否已设置为 10?如果是,完成。 - 执行更新工作——这涉及在
ROLLBACK
的情况下保存现有行,暂时存储新值,等等——这一步可能是成本最高的一步.
第 2 步是唯一的区别 -- 这是一个非常小的步骤。在性能方面不值得担心。
另一方面,第 2 步意味着这两个更新是不同的 -- 如果 bar1=4567
会发生什么?第一次更新会改变它,但第二次不会。
您的最后评论暗示也许您应该使用交易来防止一个客户踩到另一个客户。也许代码应该更像:
BEGIN;
SELECT ... WHERE id = 5000 FOR UPDATE;
decide what to do -- which might include ROLLBACK and exit
UPDATE Foo SET bar1=10 WHERE id = 5000;
COMMIT;
底线:使用事务而不是额外的代码来处理并发。
警告:交易应该“快”(少于几秒)。如果您需要一个“长”事务(例如,可能需要几分钟才能完成的 'shopping cart'),则需要一种不同的机制。如果您需要长期交易,请开始一个新问题来解释情况。 (当前问题是讨论单个Update的性能。)