20

標準の RODBC パッケージのsqlSave関数は、単一のINSERTステートメント (パラメーターfast = TRUE) であっても、最小限の負荷ではないため、大量のデータに対して非常に遅くなります。最小限のログ記録で SQL サーバーにデータを書き込むにはどうすればよいでしょうか?

現在試行中:

toSQL = data.frame(...);
sqlSave(channel,toSQL,tablename="Table1",rownames=FALSE,colnames=FALSE,safer=FALSE,fast=TRUE);
4

2 に答える 2

32

ローカルで CSV にデータを書き込んでからBULK INSERT( に似た事前構築済みの関数としてすぐには利用できないsqlSave) を使用すると、データを MS SQL Server に非常に迅速に書き込むことができます。

toSQL = data.frame(...);
write.table(toSQL,"C:\\export\\filename.txt",quote=FALSE,sep=",",row.names=FALSE,col.names=FALSE,append=FALSE);
    sqlQuery(channel,"BULK
                INSERT Yada.dbo.yada
                FROM '\\\\<server-that-SQL-server-can-see>\\export\\filename.txt'
                WITH
                (
                FIELDTERMINATOR = ',',
                ROWTERMINATOR = '\\n'
                )");

SQL Server には、CSV ファイルを保持するネットワーク フォルダーにアクセスするためのアクセス許可が必要です。アクセス許可がない場合、このプロセスは機能しません。さまざまなアクセス許可を設定する必要がありますが (ネットワーク フォルダーとBULK ADMIN特権、速度の見返りは無限に価値があります)。

于 2013-10-04T21:03:30.257 に答える
0

tinyBULK INSERTではないデータに対しては、これが正しいオプションであることに完全に同意します。ただし、デバッグ メッセージなどを 2 ~ 3 行追加する必要がある場合は、やり過ぎのようです。BULK INSERT

あなたの質問への答えはDBI::dbWriteTable()関数です。以下の例 (R コードをAWS RDSのインスタンスに接続していますMS SQL Express):

library(DBI)
library(RJDBC)
library(tidyverse)

# Specify where you driver lives
drv <- JDBC(
  "com.microsoft.sqlserver.jdbc.SQLServerDriver",
  "c:/R/SQL/sqljdbc42.jar") 

# Connect to AWS RDS instance
conn <- drv %>%
  dbConnect(
    host = "jdbc:sqlserver://xxx.ccgqenhjdi18.ap-southeast-2.rds.amazonaws.com",
    user = "xxx",
    password = "********",
    port = 1433,
    dbname= "qlik")

if(0) { # check what the conn object has access to
  queryResults <- conn %>%
    dbGetQuery("select * from information_schema.tables")
}

# Create test data
example_data <- data.frame(animal=c("dog", "cat", "sea cucumber", "sea urchin"),
                           feel=c("furry", "furry", "squishy", "spiny"),
                           weight=c(45, 8, 1.1, 0.8))
# Works in 20ms in my case
system.time(
  conn %>% dbWriteTable(
    "qlik.export.test",
    example_data
  )
)

# Let us see if we see the exported results
conn %>% dbGetQuery("select * FROM qlik.export.test")

# Let's clean the mess and force-close connection at the end of the process
conn %>% dbDisconnect()

転送される少量のデータに対してはかなり高速に動作し、必要に応じてかなりエレガントに見えますdata.frame->SQL tableソリューション。

楽しみ!

于 2017-06-14T01:38:55.873 に答える