Mo.*_*Mo. 13 python mysql pymysql
所以我有一个python脚本,它通过大约350,000个数据对象,并且根据一些测试,它需要更新一行代表MySQl数据库中每个对象.我也使用pymysql,因为我遇到的问题最少,特别是在发送大型选择查询时(select语句where column IN (....)
包含可能包含100,000+以上的值).
由于每行的每次更新可能不同,因此每个更新语句都不同.例如,对于一行,我们可能想要更新,first_name
但对于另一行,我们希望first_name
保持不变,我们想要更新last_name
.
这就是为什么我不想使用cursor.executemany()
接受一个通用更新语句的方法,然后你给它提供值,但是正如我所提到的,每次更新都是不同的,所以有一个通用的更新语句对我的情况不起作用.我也不想通过网络单独发送超过350,000个更新语句.无论如何,我可以将所有更新语句打包在一起并立即发送它们吗?
我尝试在一个查询中使用它们并使用该cursor.execute()
方法但它似乎并不更新所有行.
小智 5
如果您可以将"测试"编码到SQL逻辑本身中,那么您的最佳表现就是如此,因此您可以将所有内容都归结为少数UPDATE语句.或者至少以这种方式尽可能多地完成,以便需要更少的行单独更新.
例如:
UPDATE tablename set firstname = [some logic]
WHERE [logic that identifies which rows need the firstname updated];
Run Code Online (Sandbox Code Playgroud)
你没有详细描述你的测试,所以很难确定.但是通常可以通过一些工作在WHERE子句中获得相当多的逻辑.
另一种选择是将您的逻辑放入存储过程.你仍然会做350,000次更新,但至少他们并非都是"通过网络".不过,我会将此作为最后的手段使用; 业务逻辑应尽可能保留在应用程序层中,并且存储过程使您的应用程序不那么可移植.
SQL #1:CREATE TABLE t
使用您可能需要更改的任何列。制作全部NULL
(与 相对NOT NULL
)。
SQL #2:执行批量INSERT
(或LOAD DATA
)所有需要的更改。例如,如果仅更改first_name
,则填写id
和first_name
,但具有其他列NULL
。
SQL#3-14:
UPDATE real_table
JOIN t ON t.id = real_table.id
SET real_table.first_name = t.first_name
WHERE t.first_name IS NOT NULL;
# ditto for each other column.
Run Code Online (Sandbox Code Playgroud)
除了 #1 之外的所有 SQL 都将非常耗时。而且,由于UPDATE
需要构建撤消日志,因此可能会超时或出现其他问题。如有必要,请参阅分块的讨论。
COALESCE()
如有必要,请使用、GREATEST()
、IFNULL()
等函数。
质量UPDATEs
通常意味着糟糕的模式设计。
(如果瑞安跳出来给出一个“答案”而不仅仅是一个“评论”,他可能应该得到“赏金”。)
归档时间: |
|
查看次数: |
983 次 |
最近记录: |