꽤 간단한 저장 프로 시저를 올바르게 만드는 데 어려움을 겪고 있습니다. 다음 문서 테이블 조각 고려 : 복사 (copy-on-write)을 사용하여,MySQL의 저장된 함수를 올바르게 루프하는 방법은 무엇입니까?
id replaced_by baseID
1 2 0
2 3 0
3 0 0
간단한 계층 테이블을. 아티클을 편집하면 현재 아티클의 replaced_by 필드가 새 복사본의 id로 설정됩니다.
나중에 article의 baseID를 저장해야하는 baseID 필드를 추가했습니다. 위 예에서 한 개의 기사 (예 : id 3)가 있습니다.
SELECT getBaseID(3);
: 실제로 사용하여 함수를 호출 할 때까지, 그것은 간단한데
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 ;
: 그것은 baseID 1.
가 baseID를 얻으려면 것입니다, 나는 다음과 같은 저장 프로 시저를 만들었습니다 함수가 1을 반환 할 것으로 기대합니다. 두 번째 슬라이스를 취할 수도 있음을 이해하고 있습니다. 대신, 머신의 CPU는 100 % (mysqld)까지 올라간다.
REPEAT .. UNTIL
과 WHILE .. DO
을 사용하여 동일한 기능을 다시 작성한 경우에도 동일한 결과가 나타납니다.
누군가 내 CPU가 루프에 들어갈 때 왜 CPU가 100 % 올라가는지 설명 할 수 있습니까?
사이드 노트 : 시간을 단순히 얻으려고합니다. 나는 PHP에서 똑같은 함수를 만들었지 만 괜찮습니다.하지만 MySQL은 약간 더 빨리 할 수 있습니다. 우리는 약 1 천 8 백만 건의 기록을 살펴 봐야합니다. 내가 구할 수있는 시간은 그만한 가치가있을거야.
도움 및/또는 조언을 미리 보내 주셔서 감사합니다.
해결 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 ;
감사합니다. 나는 INTO 비트에서 정확히 그 페이지를 읽었지 만, 변화가없는 vars로 무엇을 의미하는지 이해하지 못했습니다. – djBo