djB*_*jBo 8 mysql loops stored-functions
我很难获得一个非常简单的存储过程.请考虑以下文章表格片段:
id replaced_by baseID
1 2 0
2 3 0
3 0 0
Run Code Online (Sandbox Code Playgroud)
一个简单的分层表,使用copy-on-write.编辑文章时,当前文章的replacement_by字段将设置为其新副本的ID.
我添加了一个baseID字段,将来应该存储一篇文章的baseID.在上面的例子中,有一篇文章(例如id 3).它的baseID是1.
为了获取baseID,我创建了以下存储过程:
DELIMITER $$
CREATE FUNCTION getBaseID(articleID INT) RETURNS INT
BEGIN
DECLARE x INT;
DECLARE y INT;
SET x = articleID;
sloop:LOOP
SELECT id INTO y FROM article WHERE replaced_by_articleID = x;
IF y IS NOT NULL THEN
SET x = y;
ITERATE sloop;
ELSE
LEAVE sloop;
END IF;
END LOOP;
RETURN x;
END $$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
这看起来很简单,直到我实际调用函数使用:
SELECT getBaseID(3);
Run Code Online (Sandbox Code Playgroud)
我希望,函数返回1.我甚至愿意理解它可能需要一秒钟.相反,机器的CPU上升到100%(mysqld).
我甚REPEAT .. UNTIL至用WHILE .. DO相同的最终结果重写了相同的函数.
任何人都可以解释为什么我的CPU在进入循环时会上升100%?
旁注:我想简单地赢得时间.我已经在PHP中创建了完全相同的函数,它执行得很好,但我们猜测MySQL可以稍微快一些.我们需要筛选大约1800万条记录.我可以节省的任何时间都值得.
提前感谢任何帮助和/或指示.
解决了SQL:
DELIMITER $$
CREATE FUNCTION getBaseID(articleID INT) RETURNS INT
BEGIN
DECLARE x INT;
DECLARE y INT;
SET x = articleID;
sloop:LOOP
SET y = NULL;
SELECT id INTO y FROM article WHERE replaced_by_articleID = x;
IF y IS NULL THEN
LEAVE sloop;
END IF;
SET x = y;
ITERATE sloop;
END LOOP;
RETURN x;
END $$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)