我有一个大表(500万行),有一个名为'unique_id'的唯一标识符列
我正在通过Node.js(node-mysql
绑定)运行INSERT查询,并且可能会尝试插入重复项。
这两个解决方案是:
1)将'unique_id'作为索引,并在INSERT之前检查整个数据库是否有重复记录:
'SELECT unique_id WHERE example = "'+unique_id+'" LIMIT 1'
2)使'unique_id'成为MySQL中的唯一索引,并执行INSERT 而不用检查重复项。显然,任何重复都会导致错误而不会被插入表中。
我的预感是解决方案2)更好,因为它可以防止搜索更糟糕的(500万 - 1)行的副本。
使用解决方案2是否有任何缺点?)
答案 0 :(得分:2)
为unique_id列定义唯一的主索引有很多好处:
使用第二个解决方案,您可能需要处理插入重复的尝试(除非您的唯一ID由MySQL生成)。
自动增量主索引: https://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html
答案 1 :(得分:1)
令人惊讶的是,它在性能方面没什么区别。搜索将使用(并要求)相同的索引。
然而,你的(2)解决方案的优点是什么性能差异很小。
实际上在MySQL中你可以使用IGNORE关键字完全消除错误:
INSERT IGNORE INTO ... VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)...;
将始终成功(将跳过插入重复项)。这允许在单个语句中插入多个值,如上所述。
您可能也对ON DUPLICATE KEY UPDATE
系列技巧感兴趣: - )。
真正的区别,如M.M.已经说明,是诚信。使用UNIQUE索引约束,您可以确定您的数据;否则,你需要在检查它和插入新元组的那一刻之间锁定表,以避免其他人插入相同值的风险。
如果数据的“重复性”需要重要的业务逻辑工作,那么您的(1)解决方案可能会占有一席之地,这不能轻易地转换为MySQL约束。在那种情况下你会
(可能有充分理由认为,做这么复杂的旋转木马的必要性源于数据库设计中的一些错误。理想情况你应该能够在MySQL中做所有事情但是商业现实有时会远非理想。