通过 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)(或至少这些列的某些子集)上有一个复合索引。