【问题标题】:dbwritetable from multiple R studio sessions to same SQL table concurrentlydbwritetable 从多个 R studio 会话同时到同一个 SQL 表
【发布时间】:2019-02-16 23:48:46
【问题描述】:

我从 RStudio 启动了 4 个会话,我在任务管理器上看到了 4 个“R Studio R 会话”。我在每个会话和 dbwritetable 中使用相同的 dsn 名称连接到同一个 SQL 数据库表。

conn<-dbConnect(odbc::odbc(),"server",database="x_test")

dbWriteTable(conn,"x_testbl",export,overwrite=FALSE,append=TRUE)

请注意,export 是一个 data.table,它与正在写入的 SQL 表具有相同的列,并且会话中的每个“export”表都将是相对唯一的,但某些列可能具有相同的值(自然)。

我希望在每个会话中同时执行多个写入。每个会话执行一些计算,然后 dbwritetable 将 data.table 写入 SQL 表。这会引起任何问题吗?我能做些什么来确保没有问题吗?谢谢!

【问题讨论】:

  • @RYoda 感谢您的回复,请参阅上面的编辑。
  • Microsoft SQL Server 标准(64 位)版本:13.0.4001.0
  • @RYoda 我这样做:我去 RStudio 中的会话并开始“新会话”。我这样做了4次。我在任务管理器中看到 4 个“R Studio R session”。我希望在每个会话中运行相同的脚本。
  • 好的,我看不出这在 R 端失败的任何原因。数据库正在处理并发插入,可能最好通过dbBegindbCommit 使用事务,但它不应该是必需的。我将使用 MS-SQL 2016 进行快速测试...
  • @RYoda 感谢您的宝贵时间!我希望做 4 节课,这样我就可以基本上并行写作并减少总时间。如果您需要更多信息,请告诉我。

标签: r rstudio dbi


【解决方案1】:

如果在同一 SQL Server 2016 版本上测试过您的代码 使用SQL Server Native Client 11.0(我没有安装你的驱动)并跟踪在服务器上执行的SQL代码。

我正在使用iris 数据集:

dbWriteTable(con, "iris", iris, overwrite = FALSE, append = TRUE)

odbc 包基本上发出这些命令(准备好的语句):

declare @p1 int
set @p1=9
exec sp_prepare @p1 output,N'@P1 float,@P2 float,@P3 float,@P4 float,@P5 varchar(255)',N'INSERT INTO "iris" ("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species")
VALUES (@P1, @P2, @P3, @P4, @P5)',1
select @p1

exec sp_execute 9,5.0999999999999996,3.5,1.3999999999999999,0.20000000000000001,'setosa'
[... multiple inserts...]

exec sp_unprepare 9

因此,除了通常的 SQL Server 之外,没有在多个会话中并行运行代码的风险,例如行的非确定性插入顺序(如果您尝试重现该行为,可能会导致同一插入行的不同 autoinc 值)。

您还将有四个打开的连接(完全没有问题)。

如果您的目标是插入性能,可以使用 SQL Server 的不同批量插入方法,但 dbWriteTable 的性能非常好(如果您使用最新版本)。

有关通过odbc 包进行“批量上传”的详细信息,请参阅:

https://github.com/r-dbi/odbc/issues/34

稍后添加:

会话中的每个“导出”表都是相对唯一的 但某些列可能具有相同的值(自然)。

如果你的目标表没有主键也没问题 插入重复的行(直到你想重新识别单个 行,但这是纯 SQL 问题)。您可以使用 high-low 模式向您的data.tables 添加一个 ID 行来解决此问题(high = 每个会话的唯一值,low = 1:NROW(data) 的 R 序列,然后添加高值,例如。“10000000 " 这样整体 ID 在您的整个会话中都是唯一的 - 但当然会有差距)。

【讨论】:

    【解决方案2】:

    如果多个会话同时尝试更新同一记录,这可能会导致问题。其中一个会话可以锁定记录,因此另一个会话无法更新它。 您可以有一个会话来执行所有事务,而不是 4 个会话。

    【讨论】:

      猜你喜欢
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-06
      • 2010-10-21
      • 1970-01-01
      • 2014-01-02
      相关资源
      最近更新 更多