1

我已经在MySQL中编写了一个存储过程,以便当前在表中取值并“归一化”它们。这意味着对于传递给存储过程的每个值,它会检查该值是否已经在表中。如果是,那么它将该行的id存储在一个变量中。如果该值不在表中,则它存储新插入的值的ID。然后存储过程采用这个id并将它们插入一个相当于原来的非规范化表的表中,但这个表完全标准化并且主要由外键组成。MySQL规范化存储过程性能

这个设计的问题在于存储过程需要大约10ms左右才能返回,当您试图通过一些1000万条记录时,这太长了。我的怀疑是,表演与我在做插入的方式有关。即

INSERT INTO TableA 
(first_value) 
VALUES 
(argument_from_sp) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id); 

SET @TableAId = LAST_INSERT_ID(); 

的“对重复密钥更新”是一个黑客位的,因为事实上,关于重复的键,我不想进行任何更新而只是返回值的行的ID。如果您错过了这一步,LAST_INSERT_ID()函数会在您尝试运行“SET ...”语句时返回错误的值。

有谁知道更好的方法来做到这一点在MySQL?

回答

2

我已经回到并创建了一个功能,而不是处理这种情况:

CREATE DEFINER=`root`@`%` FUNCTION `value_update`(inValue VARCHAR(255)) RETURNS int(11) 
BEGIN 
     DECLARE outId INT; 
     SELECT valueId INTO outId FROM ValuesTable WHERE value = inValue; 

     IF outId IS NULL THEN 
       INSERT INTO ValuesTable (value) VALUES (inValue); 
       SELECT LAST_INSERT_ID() INTO outId; 
     END IF; 

     RETURN outId; 
END 

前面提到的存储过程调用这些函数,而不是在做INSERT语句本身。性能方面,上述功能在我的设置中更快(使用ndb表格类型)。此外,在对应用程序的所有部分进行基准测试后,我发现这造成的性能问题只是整体性能瓶颈的一小部分。

0

如果您已经有一个唯一的标识符,是否需要有一个自动递增的主键?

+0

唯一标识符否则会是VARCHAR字段。由于性能原因,我宁愿使用整数字段。 – srkiNZ84 2010-07-25 23:15:23

+0

唯一标识符仍然是一个varchar字段;你所做的一切就是在表格中添加另一列和另一个唯一的索引。整数唯一标识符没有任何用处,可以说最好的是它不会让事情变得非常缓慢。 对应用程序的所有部分进行基准测试是一个不错的主意,可以让您专注于重要的事情。 – 2010-07-26 08:13:51