【发布时间】:2011-05-04 23:24:45
【问题描述】:
我有一个处理在树中添加节点的存储过程。基本上表结构是
id INT PRIMARY
label VARCHAR(1) /* the value of the node which is a character */
parent_id INT /* id of the parent node */
这是我的存储过程:
/*
takes a word, and adds every character in to the table
where every character is a child of the previous character
the first character of every word is a child of the root
*/
CREATE PROCEDURE rule(IN word VARCHAR(255))
BEGIN
/* (parent_id = 0) => child of root */
DECLARE pid INT DEFAULT 0; /* parent id */
DECLARE npid INT DEFAULT 0;
DECLARE strlength INT;
DECLARE j INT DEFAULT 1;
DECLARE query_count INT DEFAULT 0;
DECLARE active_char VARCHAR(1);
SET strlength = LENGTH(word);
/* loop through the word */
WHILE j <= strlength DO
/* get a single character from word */
SET active_char = SUBSTR(word,j,1);
/* if the character doesn't already exist, insert it */
SELECT COUNT(*) INTO query_count FROM tree
WHERE parent_id = pid AND label = active_char;
IF (query_count = 0) THEN
INSERT INTO tree (label, parent_id)
VALUES (active_char,pid);
END IF;
/* Set the new parent id */
SELECT id INTO npid FROM tree
WHERE label = active_char AND parent_id = pid;
SET pid = npid;
SET j = j + 1;
END WHILE;
END //
我确信我可以进行一些调整以使程序更有效率,但我想不出任何可以显着减少所需时间的方法。
我正在处理很多单词,这意味着此过程运行了 100,000 次,这反过来意味着大量插入和大量查询。这需要几个小时甚至几天(不确定,因为我放弃了等待并停止了这个过程)。
问题是,我认为我不能进行批量插入,因为每个插入都依赖于前一个插入。
我想知道是否有某种方法可以创建一个存储在主内存中的虚拟表以快速执行所有这些操作,然后将结果保存到实际表中。
目前,我能想到的唯一可能的解决方案是在 PHP 中构建树,然后进行批量插入。我认为这应该更快,但我不确定到什么程度。
任何帮助将不胜感激。
谢谢。
【问题讨论】:
-
这在数据库之外可能会更快,因为它不需要担心 IO 和一致性。
-
您要插入的表格是什么样的?任何索引?主键?
-
该表有 3 个字段。 id、label 和 parent_id,其中 id 为主键。没有索引。
-
使用 last_insert_id() 应该消除最后一个查询。你为什么要检查一个你没有插入的字符是否已经存在?
标签: mysql sql database stored-procedures