更快速地进行单独插入?

时间:2011-05-04 23:24:45

标签: mysql sql database stored-procedures

我有一个存储过程,用于处理在树中添加节点。基本上表结构是

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 //

我确信我可以做一些调整来使程序更有效率,但我想不出任何可以大大减少所需时间的事情。

我正在处理很多单词,这意味着这个程序运行了几十万次,这反过来意味着大量的插入和大量的查询。它可能需要几个小时或几天(不确定因为我放弃了等待并停止了这个过程)。

问题是,我认为我不能进行批量插入,因为每个插入都取决于之前的插入。

我想知道是否有某种方法可以创建一个存储在主内存中的虚拟表来快速执行所有这些操作,然后将结果保存到实际的表中。

目前,我能想到的唯一可能的解决方案是在PHP中构建树,然后进行批量插入。我认为这应该更快,但我不确定到什么程度。

任何帮助都会非常感激。

感谢。

2 个答案:

答案 0 :(得分:0)

虽然我担心我不能声称自己已经使用过它,但是将数据作为XML传递给存储过程并将其作为described here处理似乎是一种合理的方法。注: MySQL 5.1或更高版本。

答案 1 :(得分:0)

一些想法:

  1. “缩短时间”意味着您必须向我们展示架构,索引,查询和EXPLAIN(过程中的每个语句)。
  2. 使用INSERT IGNORE代替您现在使用的SELECT/INSERT对。
  3. 您无需SELECT ID退出 - 使用LAST_INSERT_ID()
  4. 为什么选择进入npid然后复制到pid?只需选择进入pid。