【问题标题】:How to quickly export data from R to SQL Server如何快速将数据从 R 导出到 SQL Server
【发布时间】:2013-10-12 00:20:02
【问题描述】:

标准 RODBC 包的 sqlSave 函数即使作为单个 INSERT 语句(参数 fast = TRUE)由于非最小加载对于大量数据来说非常慢。如何以最少的日志记录将数据写入我的 SQL 服务器,使其写入速度更快?

目前正在尝试:

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

【问题讨论】:

    标签: sql sql-server r bigdata


    【解决方案1】:

    通过在本地将数据写入 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 权限,但速度奖励更有价值)。

    【讨论】:

    • 只是一个关于@Jpd527 提供的解决方案的问题。我认为 filename.txt 应该是 filename.csv 是否正确?只是您提到将数据保存为 csv 会有所帮助,但我似乎没有在您的解决方案中看到 CSV。
    • 你会这么认为,但BULK INSERT 命令很挑剔,需要.txt。文件的实际内容与 CSV 相同;唯一的区别是语义文件结尾使 SQL 快乐。
    • 感谢@jpd527,这太棒了。我对 .csv 文件有类似的情况和同样的疑问。谢谢一声。
    【解决方案2】:

    我完全同意BULK INSERT 是任何非微小数据的正确选择。 但是,如果您需要添加 2-3 行,例如调试消息它BULK INSERT 似乎是一个矫枉过正。

    您的问题的答案是DBI::dbWriteTable() 函数。下面的示例(我将我的 R 代码连接到 AWS RDSMS 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 解决方案,它看起来相当优雅。

    享受吧!

    【讨论】:

    • RJDBC 比 RODBC 慢得多,而且设置起来也困难得多。标准 sqlSave 仅在几行内以同样可忽略的毫秒数返回。
    猜你喜欢
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多