我有一个全天定期更新的表,所以我正在寻找最可扩展的更新行的方法。这些更新大批量发生,因此每次更新可能包含大约1000行。
目前,我循环遍历这1000行中的每一行并运行单个更新查询...虽然执行时间不长,但与一个简单的大量插入语句相比,它似乎很浪费。因此REPLACE INTO是有道理的,因为它基本上删除旧行并插入新行,但是如何与手动“删除数组中的id”然后批量插入相比?完全一样?稍微不一样?有更好的方法吗?
这里的关键是这些不是单行查询,而是大规模行查询。所以问题是,运行这些更新的最具可扩展性的方法是什么。我说“可扩展”而不是“最快”,因为这些更新会在具有活动用户的生产服务器上定期发生,因此速度很重要,但不能以锁定服务器为代价。
答案 0 :(得分:4)
你想使用InnoDB而不是MyISAM。为什么?因为当您执行批量插入和删除操作时,将整个事物包装在事务中可以提高巨大性能。
无论你最终对数据做了什么,这种改变本身就是巨大的。
使用an appropriate transaction isolation level,您的用户可以在更改所有内容时继续使用该表,只需在提交后查看更改,而无需担心表锁。
关于实际数据更新,避免删除。删除慢。进行更新,并仅删除您需要更新的内容。避免使用REPLACE INTO
魔法,因为它在插入之前会删除。
答案 1 :(得分:0)
我不推荐InnoDB。使用它似乎是合乎逻辑的,因为论文说这是为了这个目的而行级锁定是一件好事 - 现在每当我们尝试它时我们发现它比MyISAM慢,慢得多,这一点永远无法通过锁定差异得到的结果得到补偿。它根本不值得。
相反,我试图回答原来的问题。
UPDATE是最快的方式。
周期。
REPLACE几乎不是正确的方法。
在某些情况下,它更像是一个避免交易的补丁,而且效果很好;但是无论何时你可以管理,都要做一个SELECT COUNT,以确定你是否有相同密钥的行,如果答案为是则选择UPDATE,否则选择INSERT。是的,这意味着3个独立的步骤,而不是一个,我知道。这就是为什么我说"每当你能管理"。所以,再次:COUNT加UPDATE更快 - 另一方面,REPLACE是" atomic"。
啊,是的,忘了提及:从MySQL 4.1+开始,你有" INSERT ON DUPLICATE KEY UPDATE"这一步完成所有这些。
如果可能,请将您的行设置为固定大小 - 这会使UPDATE更快。
如果您的表显示"行大小:动态"在PMA中,您的行可以增长/缩小,而且不是免费的。 VARCHAR和其他文本字段通常会这样做。现在,如果你有一个小行并将其更新为更大的行,显然UPDATE需要寻找更大的空间来适应新行并删除原来的行。换句话说,在这种情况下,MySQL会执行类似插入和删除的操作。它的代价很高。如果有方法,请对需要频繁更新的表使用固定行。这也将减少"表开销"。
您可以使用单个查询更新多行
在mysql中,你有CASE - 所以你可以做"更新我的所有行,如果id = 1则将名称设置为Jennifer,如果id = 2则设置为George,......"。如果有很多字段,使用它进行更新是很复杂但是,你可以这样做,有一种方法,你可以将它包装在php函数中,以便将来只查询长度。这样,您的更新就是原子的。你可以称之为穷人的交易"。
许多更新优于一个
如果您有很多用户,显然您不想锁定查询超过几毫秒。在这种情况下,执行更多UPDATE比单个大事务要好得多,因为其他进程可以完成工作并同时访问相同的表。