我试图在包含100000s行的数据库中选择100s行,并在之后更新这些行。
问题是我不想为了这个目的两次访问DB,因为update只将那些行标记为"read“。
有没有什么方法可以用简单的jdbc库在java中做到这一点?(希望不使用存储过程)
更新:好的,这里有一些澄清。
有几个运行在不同服务器上的相同应用程序的实例,它们都需要根据creation_date列选择100个“未读”行,读取其中的blob数据,将其写入文件并通过ftp将该文件发送到某个服务器。(我知道史前时代,但需求就是需求)
读取和更新部分是为了确保每个实例获得不同的数据集。(按照顺序,像赔率和偶数这样的把戏不会奏效:/)
我们选择要更新的数据。数据通过网络传输(我们一直在等待),然后我们将它们更新为"READ“。然后释放锁以进行读取。整件事花的时间太长了。通过同时读取和更新,我希望减少锁定时间(从我们使用select进行更新到实际更新的时间),这样使用多个实例将增加每秒读取行数。
还有想法吗?
发布于 2009-01-03 13:57:41
在我看来,这里可能有不止一种方式来解释这个问题。
让我们先采用选项1,因为这似乎是最简单的。您不需要选择行来更新它们,只需使用WHERE子句执行更新即可:
update table_x
set read = 'T'
where date > sysdate-1;
查看选项2,您希望在用户已读取它们(或下游系统已接收它们,等等)时将它们标记为已读。为此,您可能需要进行另一次更新。如果查询主键,除了在第一个select中需要的其他列之外,还可以更容易地进行更新,因为数据库不必通过表或索引扫描来查找行。
在JDBC (Java)中,有一个执行批量更新的工具,您可以一次执行一组更新。当我需要执行许多完全相同形式的更新时,这是很好的解决方案。
选项3,您希望在一次拍摄中选择和更新所有内容。就我个人而言,我没有发现这有多大用处,但这并不意味着其他人没有,我认为某种存储过程会减少往返。我不确定您在这里使用的是什么db,也不能真正提供细节。
发布于 2009-01-03 13:25:01
去数据库并不是那么糟糕。如果你没有‘通过网络’返回任何东西,那么更新应该不会对你造成太大的破坏,它只有几十万行。你担心什么?
发布于 2009-01-03 13:41:45
如果您在JDBC中执行SELECT操作并遍历ResultSet来更新每一行,那么您这样做是错误的。这是一个永远不会表现良好的(n+1)查询问题。
只需使用WHERE子句执行更新即可,该子句确定需要更新其中的哪些行。这是一个单一的网络往返。
不要过于以代码为中心。让数据库完成它设计的任务。
https://stackoverflow.com/questions/409849
复制