我有类似下面的查询:
go get golang.org/x/tools/cmd/guru
我担心MySQL可能会查看整个表并在整个数据集上设置锁定以进行更新。因此,如果这个单个UPDATE语句发生在数百万个客户身上,并且f_SumAssetCosts甚至只需要很短的时间来处理,那么整个过程可能会锁定表整整几秒,可能是几分钟。在高事务系统中,这是不可取的,客户行可能会经常读取/更新。
首先,当整个操作正在运行时,MySQL会在整个表上放置一个锁(对于UPDATE / DELETE)吗?
其次,只是为了确认我的知识,即使在UPDATE期间从这个表中选择是否仍然可以?我假设UPDATE语句尚未提交"已提交"它的更改,所以任何SELECT运行期间将返回最后的已知提交值?它不能正确锁定读取并等待UPDATE完成?
我正在考虑将SELECT Id FROM客户中的整个操作分解为临时表,然后将光标循环到表上,以便运行一个UPDATE ...调用而不执行任何大量锁定(如果我对上面的巨大锁定的假设是正确的)。
答案 0 :(得分:1)
如果您担心两者功能的成本以及正在进行的事务和锁定,那么您可能希望批量执行此操作。如果该值当前为NULL
而新值不是,那么这很容易:
UPDATE customers
SET AssetsTotal = f_SumAssetCosts(c.Id)
WHERE AssetsTotal IS NOT NULL
LIMIT 1000; -- or whatever
这将每次更新一小部分客户,限制锁定以及表格不可用的时间段。
如果值未以NULL
开始,则会变得棘手。在这种情况下,您可以将其设置为NULL
。 。 。有点贵但比功能调用便宜。
根据具体要求,还有其他方法:
truncate
并重新插入/重命名重新生成表。join
将其带入,并从另一个表中删除。注意事项是: