带有1条update语句的MySQL事务需要>;4000行表中的4s
大多数情况下,此交易需要4s!此存储过程每秒运行5-6次左右 我的存储过程非常简单(innoDB-可重复读取):带有1条update语句的MySQL事务需要>;4000行表中的4s,mysql,performance,stored-procedures,transactions,innodb,Mysql,Performance,Stored Procedures,Transactions,Innodb,大多数情况下,此交易需要4s!此存储过程每秒运行5-6次左右 我的存储过程非常简单(innoDB-可重复读取): 启动事务; 从拍卖中选择end_time到currentEndTime,其中id=var_auction_id; 如果(ADDTIME(currentEndTime,var_time_increment)
启动事务;
从拍卖中选择end_time到currentEndTime,其中id=var_auction_id;
如果(ADDTIME(currentEndTime,var_time_increment)
我想找出导致4s峰值的原因,我尝试过的方法:
SELECT end_time INTO currentEndTime FROM auctions WHERE id = var_auction_id;
IF (ADDTIME(currentEndTime, var_time_increment) < NOW()) THEN
UPDATE auctions
SET end_time = ADDTIME(NOW(), var_time_increment)
, price = price + var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;
ELSE
UPDATE auctions
SET end_time = ADDTIME(end_time, var_time_increment)
, price = price+var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;
END IF;
从拍卖中选择结束时间到当前结束时间,其中id=var\u auction\u id;
如果(ADDTIME(currentEndTime,var_time_increment)
可以重写为:
UPDATE auctions
SET end_time
= ADDTIME( CASE WHEN ADDTIME(end_time, var_time_increment) < NOW()
THEN NOW()
ELSE end_time
END
, var_time_increment
)
, price = price + var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;
更新拍卖
设定结束时间
=ADDTIME(ADDTIME(end_time,var_time_increment)
或:
更新拍卖
设定结束时间
=ADDTIME(当end_time
(closed,id)
上的复合索引也应该有助于更新
语句,以避免在关闭0时从表中读取 运行查询的服务器是否负载过重?uptime
或top
命令显示什么?还是任务管理器?(取决于操作系统)这是最重要的信息:最高负载平均值:0.97、0.89、0.91个任务:总共201个,3个正在运行,198个正在休眠,0个停止,0个僵尸Cpu:21.7%的us,1.5%的sy,0.0%的ni,76.4%的id,0.0%的wa,0.2%的hi,0.2%的si,0.0%的STD看起来没有过载,奇怪。。。可以尝试在两个字段id
+closed
上添加索引,精确匹配UPDATE
的WHERE
标准?此外,是什么提供了一个免费-m
?您还可以检查您的MySQL设置是否针对InnoDB进行了优化(5.0的默认设置对于MyISAM很好,但对于InnoDB的使用通常不太好)。您可以从这里开始:表上的主键是什么?innodb缓冲池有多大?您可能在检查点期间遇到innodb暂停。当您遇到问题时,监视show innodb status
的输出。如果id
是主键,则复合索引将无济于事。如果它不是主键,那么表需要重新设计。@TheScrumeMeister:为什么它没有帮助(如果id
是PK)?条件id=var\u auction\u id和closed=0
意味着如果没有复合索引,查询必须读取表。id确实是主键。我用select对update语句进行了解释,它似乎是从index读取的。@ypercube,您介意解释一下您的建议的潜在好处吗?我想我不明白。如果多个客户机运行此事务,那么他们中的一个客户机是否能够将close设置为0,而其他客户机是否能够将write closed设置为0,从而没有浪费的读取?我错过什么了吗?谢谢我的(重写)建议与如何使用或更改closed
无关。它只意味着避免第一个只获取结束时间的SELECT
。
UPDATE auctions
SET end_time
= ADDTIME( CASE WHEN ADDTIME(end_time, var_time_increment) < NOW()
THEN NOW()
ELSE end_time
END
, var_time_increment
)
, price = price + var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;
UPDATE auctions
SET end_time
= ADDTIME( CASE WHEN end_time < ADDTIME(NOW(), - var_time_increment)
THEN NOW()
ELSE end_time
END
, var_time_increment
)
, price = price + var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;