我有一些困难得到一个非常简单的存储过程的权利。 考虑下面的文章表片断:如何在MySQL中正确循环存储的函数?
id replaced_by baseID
1 2 0
2 3 0
3 0 0
一个简单的分级表,使用写入时复制。编辑文章时,当前文章的replaced_by字段被设置为其新副本的标识。
我已经添加了一个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 ;
这看起来很简单,直到我用实际调用该函数:
SELECT getBaseID(3);
我期望,函数返回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 ;
Omg,非常感谢。我确实读到了INTO位上的那个页面,但我不明白他们的意思是变量不会改变。 – djBo