我有两个表-- accounts和inf_accounts。从inf_accounts到accounts每天有数百万行的更新。
我尝试了两个更新:
UPDATE accounts acc SET account_status=(SELECT account_status FROM inf_accounts inf WHERE acc.account_number = inf.account_number);
字符串
这一个在5-7分钟内执行OK -10 M行更新。问题是,它不像预期的那样工作。当帐户表中有行在inf_accounts中找不到时,它显然会崩溃。
UPDATE accounts acc SET account_status=inf.account_status FROM inf_accounts inf WHERE acc.account_number = inf.account_number;
型
这一个工作正常,但执行可怕的-10 M行更新在几十分钟内。
有没有办法做得更好?
2条答案
按热度按时间mhd8tkvw1#
在第二个示例语句中,
字符串
这将使DBMS避免更新状态已经正确设置的行。如果这是大多数行,它将节省保存大量时间。
2ledvvac2#
一种方法是查看执行
UPDATE
时要访问的数据集。您可以通过查看SELECT
在相同参数下的结果来实现这一点,并通过EXPLAIN
:字符串
这可能会显示是否使用索引来比较
acc.account_number
和inf.account_number
。如果没有,那么您可能需要花费很长时间来连接两个表,以确定要更新accounts
的哪些行。另外,正如在另一个答案中提到的
O. Jones
,没有限制accounts
中的哪些行要更新。如果没有AND acc.account_status <> inf.account_status
,即使acc.account_status
已经等于inf.account_status
,也会设置acc.account_status
,导致不必要的写入,从而占用额外的时间。如果还没有,请确保对两个表上的
account_status
和account_number
列都建立索引。EXPLAIN
可能有助于确定UPDATE
调用中的实际瓶颈(注意,EXPLAIN
不会运行查询,而只显示执行计划。如果您想查看实际的运行时性能,请改用EXPLAIN ANALYZE
)