如何最小化程序的处理时间?
How to minimize process time of the procedure?
我创建了一个非常复杂的存储过程,用于检查 c_sent_messages
table 中的密码是否存在于 c_passwords
table 中。然后它输入一些消息并更新数据库中的记录。最后是从c_sent_messages
到archive
table的记录。在我添加将记录添加到 archive
并从 c_sent_messages
中删除消息的两行之前一切都很好(不膨胀存储)
INSERT INTO archive SELECT *, NOW() FROM c_sent_messages WHERE id=idi;
DELETE FROM c_sent_messages WHERE id=idi;
我的处理器也是一个不错的处理器(Intel 7700 HQ),我不是 运行 任何其他 software/process。
在我添加这两行之后,该过程将记录添加到 archive
table 花费了太多时间。我想尽量减少此过程的处理时间。有什么办法让它更快吗? (添加 1000 条记录到 archive
花了 120 秒)
DELIMITER $$
CREATE PROCEDURE flood ()
BEGIN
DECLARE i INT DEFAULT 0;
declare ifExist int DEFAULT 0;
DECLARE numara VARCHAR(10);
declare adamin_gonderdigi varchar(150);
declare idi int default 0;
myloop: LOOP
SET idi = (SELECT id from c_sent_messages where stats = 'N' limit 1);
SET numara = (SELECT sender from c_sent_messages where id = idi);
SET adamin_gonderdigi = (SELECT msg_text from c_sent_messages WHERE id = idi);
select count(1) into ifExist from c_passwords b WHERE adamin_gonderdigi = b.pass;
IF ifExist > 0 THEN
set ifExist = 0;
select count(1) into ifExist from c_sent_messages a WHERE a.stats ="N";
IF ifExist > 0 THEN
INSERT INTO c_received_messages ( receiver, sender, msg_text, stats, x_date )
VALUES
(numara, "5757", "Code is received successfully.", "S",NOW());
UPDATE c_passwords a SET a.stats = "S", a.x_date = NOW()
WHERE pass = adamin_gonderdigi;
update c_sent_messages set stats = 'S' where id = idi;
ELSE
INSERT INTO c_received_messages ( receiver, sender, msg_text, stats, x_date )
VALUES(numara,"5757","Code is used before!","S",NOW());
update c_sent_messages set stats = 'U' where id = idi;
END IF;
ELSE
INSERT INTO c_received_messages ( receiver, sender, msg_text, stats, x_date )
VALUES(numara,"5757","Please send a valid code!","S",NOW());
update c_sent_messages set stats = 'F' where id = idi;
END IF;
INSERT INTO archive SELECT *, NOW() FROM c_sent_messages WHERE id = idi;
DELETE FROM c_sent_messages WHERE id=idi;
SET i = i + 1;
IF
i = 900000 THEN
LEAVE myloop;
END IF;
END LOOP myloop;
END $$
DELIMITER;
- 循环开始时的 3 个 SELECT 可以用一个
SELECT
完成——参见 JOIN
。
- 你有
INDEX(stats, id)
吗?
- 看看 IODKU 是否可以替换您的 select/if/insert/update 序列。
- 尝试在不循环 900000 次的情况下在单个 SQL 语句中完成整个过程。
我创建了一个非常复杂的存储过程,用于检查 c_sent_messages
table 中的密码是否存在于 c_passwords
table 中。然后它输入一些消息并更新数据库中的记录。最后是从c_sent_messages
到archive
table的记录。在我添加将记录添加到 archive
并从 c_sent_messages
中删除消息的两行之前一切都很好(不膨胀存储)
INSERT INTO archive SELECT *, NOW() FROM c_sent_messages WHERE id=idi;
DELETE FROM c_sent_messages WHERE id=idi;
我的处理器也是一个不错的处理器(Intel 7700 HQ),我不是 运行 任何其他 software/process。
在我添加这两行之后,该过程将记录添加到 archive
table 花费了太多时间。我想尽量减少此过程的处理时间。有什么办法让它更快吗? (添加 1000 条记录到 archive
花了 120 秒)
DELIMITER $$
CREATE PROCEDURE flood ()
BEGIN
DECLARE i INT DEFAULT 0;
declare ifExist int DEFAULT 0;
DECLARE numara VARCHAR(10);
declare adamin_gonderdigi varchar(150);
declare idi int default 0;
myloop: LOOP
SET idi = (SELECT id from c_sent_messages where stats = 'N' limit 1);
SET numara = (SELECT sender from c_sent_messages where id = idi);
SET adamin_gonderdigi = (SELECT msg_text from c_sent_messages WHERE id = idi);
select count(1) into ifExist from c_passwords b WHERE adamin_gonderdigi = b.pass;
IF ifExist > 0 THEN
set ifExist = 0;
select count(1) into ifExist from c_sent_messages a WHERE a.stats ="N";
IF ifExist > 0 THEN
INSERT INTO c_received_messages ( receiver, sender, msg_text, stats, x_date )
VALUES
(numara, "5757", "Code is received successfully.", "S",NOW());
UPDATE c_passwords a SET a.stats = "S", a.x_date = NOW()
WHERE pass = adamin_gonderdigi;
update c_sent_messages set stats = 'S' where id = idi;
ELSE
INSERT INTO c_received_messages ( receiver, sender, msg_text, stats, x_date )
VALUES(numara,"5757","Code is used before!","S",NOW());
update c_sent_messages set stats = 'U' where id = idi;
END IF;
ELSE
INSERT INTO c_received_messages ( receiver, sender, msg_text, stats, x_date )
VALUES(numara,"5757","Please send a valid code!","S",NOW());
update c_sent_messages set stats = 'F' where id = idi;
END IF;
INSERT INTO archive SELECT *, NOW() FROM c_sent_messages WHERE id = idi;
DELETE FROM c_sent_messages WHERE id=idi;
SET i = i + 1;
IF
i = 900000 THEN
LEAVE myloop;
END IF;
END LOOP myloop;
END $$
DELIMITER;
- 循环开始时的 3 个 SELECT 可以用一个
SELECT
完成——参见JOIN
。 - 你有
INDEX(stats, id)
吗? - 看看 IODKU 是否可以替换您的 select/if/insert/update 序列。
- 尝试在不循环 900000 次的情况下在单个 SQL 语句中完成整个过程。