我的表格有两列:“id”(自动增量,主要)和“数字”(唯一)。现在我想要以下内容:MySQL - 如果存在,获取主键。否则,添加条目
- 如果号码已经存在,则返回id;
- else,向表中添加条目并返回其ID。
什么是最有效的方法来完成这项工作?
注:
- 有一个更大概率的数量是新的;
- 该表将包含数十万条记录。
谢谢!
我的表格有两列:“id”(自动增量,主要)和“数字”(唯一)。现在我想要以下内容:MySQL - 如果存在,获取主键。否则,添加条目
什么是最有效的方法来完成这项工作?
注:
谢谢!
INSERT IGNORE INTO table (number) VALUES (42);
SELECT id FROM table WHERE number = 42;
这可能是MySQL中最高效的。您可以使用存储过程将它们整理起来,这可能会也可能不会更有效。
编辑:
如果你认为这将是罕见的新号码上来,这将是更快:
SELECT id FROM table WHERE number = 42;
if (!id) {
INSERT INTO table WHERE number = 42;
id = SELECT @LAST_INSERT_ID;
}
有一个可能的竞争条件在这里如果并发线程同时选择则同时插入相同的号码。在这种情况下,后面的插入将失败。您可以通过在此错误情况下重新选择来恢复。
这里是一个这样的存储功能,做你的描述:
CREATE FUNCTION `spNextNumber`(pNumber int) RETURNS int(11)
BEGIN
DECLARE returnValue int;
SET returnValue := (SELECT Number FROM Tbl WHERE Number = pNumber LIMIT 1);
IF returnValue IS NULL THEN
INSERT IGNORE INTO Tbl (Number) VALUES (pNumber);
SET returnValue := pNumber; -- LAST_INSERT_ID() can give you the real, surrogate key
END IF;
RETURN returnValue;
END
使用方法如下: INSERT IGNORE INTO人物(数字)VALUES(pNumber); SET returnValue:=(SELECT Number FROM FROM WHERE Number = pNumber LIMIT 1); 我想这会更有效率? – Saad 2010-12-18 08:19:36
它将取决于重复的频率,正如克里斯在上面提到的那样......尝试不必要的插入和接触IGNORE可能会比选择...限制更昂贵1.然而,对于他关于比赛的观点条件我在这个答案中插入了IGNORE。 – Tahbaza 2010-12-18 15:01:19
感谢您的帮助Tahbaza!我已经修改了我的问题并添加了更多详细信息,请问您能确认您的解决方案仍然是最好的还是您想修改它? – Saad 2010-12-18 18:26:20
我知道这是旧的,但它是一个普遍的问题。所以,为了寻找解决方案的任何人,这里有四种不同的方式来完成这个任务与性能基准测试。 http://mikefenwick.com/blog/insert-into-database-or-return-id-of-duplicate-row-in-mysql/。
虽然这个链接可能回答这个问题,但最好在这里包含答案的基本部分,并提供参考链接。如果链接页面更改,则仅链接答案可能会失效。 – 2012-09-27 14:36:26
https://web.archive.org/web/20150915085727/http://mikefenwick.com:80/blog/insert-into-database-or-return-id-of-duplicate-row-in-mysql/ – dt192 2017-06-07 06:14:50
我能想到的最佳方式是使用存储过程,现在我无法提供示例,但请看一下 – 2010-12-17 23:51:49