gpt4 book ai didi

mysql - 带有游标的mysql程序太慢了..为什么?

转载 作者:行者123 更新时间:2023-12-01 07:42:25 25 4
gpt4 key购买 nike

我使用游标创建了一个 Mysql 过程,但它运行得太慢了......它每秒在 40 到 60 行之间......见:

DELIMITER $$
CREATE PROCEDURE sp_create(IN v_idsorteio INT,OUT afetados INT)
BEGIN
DECLARE done INT default 0;
DECLARE vc_idsocio INT;
DECLARE z INT;
DECLARE cur1 CURSOR FOR select IdSocio from socios where Sorteio=1 and Finalizado='S' and CodClientes IS NOT NULL;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
SET z=1;
OPEN cur1;
FETCH cur1 INTO vc_idsocio;
WHILE done=0 DO
-- SELECT register as t;
insert INTO socios_numeros_sorteio (IdSocio,IdSorteio,NumerodeSorteio) VALUES (vc_idsocio,v_idsorteio,z);
FETCH cur1 INTO vc_idsocio;
SET z = z+1;
END WHILE;
CLOSE cur1;
Select z-1 as total INTO afetados;
END$$
DELIMITER ;

我该如何改进?

最佳答案

这很慢,因为您正在逐行循环遍历结果集,并为返回的每一行执行单独的插入语句。这就是为什么它会很慢。

让我们简要总结一下您在做什么。首先,您正在运行一个查询:

select IdSocio
from socios
where Sorteio=1
and Finalizado='S'
and CodClientes IS NOT NULL;

(显然这些行返回的顺序并不重要。)

然后对于从该查询返回的每一行,您希望将一行插入到另一个表中。
insert INTO socios_numeros_sorteio
(IdSocio
,IdSorteio
,NumerodeSorteio
) VALUES
(vc_idsocio
,v_idsorteio
,z);

第一列的值来自查询返回的值。
第二列的值被分配了一个作为参数传递给过程的值。
第三列的值来自一个计数器,该计数器从 1 开始,每行递增 1。

MySQL 被优化为执行这样的操作。但是它没有被优化为使用逐行循环游标的存储过程来做到这一点。

如果您希望获得一些合理的性能,您需要显着减少您运行的单个 INSERT 语句的数量,而是考虑在“集合”而不是单个行中处理数据。一种方法是将行批处理为“扩展插入”语句,该语句可以一次插入多行。 (您可以在一个语句中插入的行数实际上受 max_allowed_pa​​cket 限制。)

这种方法将显着提高性能,但它不会避免游标的开销,将每一行提取到过程变量中。

像这样的东西(在你的程序的主体中)可能会执行得更好,因为它从你的选择中获取结果集并一举将所有行插入到目标表中,而不会打扰更新过程中变量的值。
BEGIN

SET @idsorteio = v_idsorteio;

INSERT INTO socios_numeros_sorteio
( IdSocio
, IdSorteio
, NumerodeSorteio
)
SELECT s.IdSocio AS IdSocio
, @idsorteio AS IdSorteio
, @z := @z+1 AS NumerodeSorteio
FROM socios s
JOIN (SELECT @z := 0) z
WHERE s.Sorteio=1
AND s.Finalizado='S'
AND s.CodClientes IS NOT NULL;

SELECT ROW_NUMBER() INTO afetados;

END$$

关于mysql - 带有游标的mysql程序太慢了..为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11549567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com