通过 MySQL 存储过程和函数更新 180k 行太慢 - 如何加速
Updating 180k rows via MySQL stored procedure & function is too slow - how to speed up
我有以下存储过程:
CREATE DEFINER=`ST`@`%` PROCEDURE `CalculateCheapestPriceALL`()
BEGIN
UPDATE
tickets
SET
tickets.Cheapest = GetCheapestTicket(tickets.STPerformerID, tickets.STVenueID, tickets.FeedID);
END
GetCheapestTicket函数如下:
CREATE DEFINER=`suprtickets`@`%` FUNCTION `GetCheapestTicket`(performerID INT(11), venueID INT(11), feedID INT(11)) RETURNS decimal(10,2)
BEGIN
DECLARE TicketPrice DECIMAL(10,2);
SET TicketPrice =
IFNULL((
SELECT
MIN(tickets.Price)
FROM
tickets
WHERE
tickets.STPerformerID = performerID
AND
tickets.STVenueID = venueID
AND
tickets.FeedID = feedID
AND
tickets.Price > 0
),0);
RETURN TicketPrice;
END
运行 存储过程目前大约需要 10 分钟,我正在寻找加快速度的方法。
下图显示了数据示例:
存储过程背后的想法是为相同的 STPerformerID 和 STVenueID 找到最便宜的价格,然后在 Cheapest 列中更新它。这样我就可以快速查找每个表演者和场地的最低价格。
大约有 2 万个人表演者,以及类似数量的场地。
感谢您的帮助。
您的基本问题是,您是 运行 为 每 行再次查找最低价格的查询,这是非常低效的。
如果将两个查询合并为一个查询。它将执行得更快:
UPDATE tickets AS t1
JOIN (SELECT STPerformerID, STVenueID, STFeedID, MIN(Price) AS cheapest
FROM tickets
WHERE Price > 0
GROUP BY STPerformerID, STVenueID, STFeedID) AS t2
USING (STPerformerID, STVenueID, STFeedID)
SET t1.Price = t2.cheapest
为了使其表现良好,请确保您在 (STPerformerID, STVenueID, STFeedID)
(或至少这些列的某些子集)上有一个复合索引。
我有以下存储过程:
CREATE DEFINER=`ST`@`%` PROCEDURE `CalculateCheapestPriceALL`()
BEGIN
UPDATE
tickets
SET
tickets.Cheapest = GetCheapestTicket(tickets.STPerformerID, tickets.STVenueID, tickets.FeedID);
END
GetCheapestTicket函数如下:
CREATE DEFINER=`suprtickets`@`%` FUNCTION `GetCheapestTicket`(performerID INT(11), venueID INT(11), feedID INT(11)) RETURNS decimal(10,2)
BEGIN
DECLARE TicketPrice DECIMAL(10,2);
SET TicketPrice =
IFNULL((
SELECT
MIN(tickets.Price)
FROM
tickets
WHERE
tickets.STPerformerID = performerID
AND
tickets.STVenueID = venueID
AND
tickets.FeedID = feedID
AND
tickets.Price > 0
),0);
RETURN TicketPrice;
END
运行 存储过程目前大约需要 10 分钟,我正在寻找加快速度的方法。
下图显示了数据示例:
存储过程背后的想法是为相同的 STPerformerID 和 STVenueID 找到最便宜的价格,然后在 Cheapest 列中更新它。这样我就可以快速查找每个表演者和场地的最低价格。
大约有 2 万个人表演者,以及类似数量的场地。
感谢您的帮助。
您的基本问题是,您是 运行 为 每 行再次查找最低价格的查询,这是非常低效的。
如果将两个查询合并为一个查询。它将执行得更快:
UPDATE tickets AS t1
JOIN (SELECT STPerformerID, STVenueID, STFeedID, MIN(Price) AS cheapest
FROM tickets
WHERE Price > 0
GROUP BY STPerformerID, STVenueID, STFeedID) AS t2
USING (STPerformerID, STVenueID, STFeedID)
SET t1.Price = t2.cheapest
为了使其表现良好,请确保您在 (STPerformerID, STVenueID, STFeedID)
(或至少这些列的某些子集)上有一个复合索引。