将 RSQLite 查询结果保存到 csv 而不将它们读入 R

Save RSQLite Query Results to csv Without Reading them into R

我正在使用一个大型 SQLite 数据库,我正在使用 RSQLite 和 Rstudio 同时 运行 许多不同的查询。很多时候查询的结果非常大,我不想将它们读入 R 然后保存到 CSV 来浪费资源。我宁愿让数据库自己管理它。但是,这不起作用,我不确定还能尝试什么。

library(RSQLite)
db <- dbConnect(RSQLite::SQLite(), "test.sqlite")

dbWriteTable(db, "iris", iris)

dbListTables(db)


sql <- ".headers on
.mode csv
.output C:/Users/jmc6538/Documents/testing/setosa.csv
SELECT * FROM iris WHERE Species = 'setosa';"

result <- dbSendQuery(db, sql)

产生这个错误

> result <- dbSendQuery(db, sql)
Error: near ".": syntax error

我试过输入各种转义字符组合,但未能解决问题。

这里的语法不被接受,因为这些指令是基于 SQLite 工具的。 这些不是简单的 sql 语句,而是此工具的命令行:

  1. here

    安装 sqlite 命令行实用程序
  2. 遵循these说明,可能需要修改以便在R中使用,例如

    shell('sqlite3 -header -csv c:/sqlite/chinook.db "select * from tracks;" > tracks.csv')

确保 SQLite3 在您的路径中,打开 cmd 并键入 sqlite3。如果出现错误 sqlite is not recognized,则需要添加包含 sqlite3.exe 或类似路径的安装文件夹。或者您可以将 R 中的工作目录设置为

setwd("C:/[installation folder containing sqlite3.exe]")
shell('sqlite3 -header -csv c:/sqlite/chinook.db "select * from tracks;" > tracks.csv')

所以我最终为此做了一些基准测试,将接受的答案与将 table 读入 R 然后保存到 csv 进行比较,因为我的目标是减少计算时间。认为其他人可能会觉得这很有帮助,而且结果相当有趣。我在我的 windows 笔记本电脑以及我可以访问的超级计算机上对其进行了测试。我为每个环境做了三个不同大小的 tables。

对于我的笔记本电脑,这是命令。

microbenchmark(
  sys = {shell('sqlite3 -header -csv C:/Users/jmc6538/Documents/testing/test.sqlite "select * from iris;" > C:/Users/jmc6538/Documents/testing/test.csv')},
  RSQLite = {
    db <- dbConnect(RSQLite::SQLite(), "test.sqlite")
    result <- dbSendQuery(db, sql)
    write.csv(dbFetch(result), "./test2.csv")
    dbClearResult(result)
    dbDisconnect(db)
  })

不同大小的 tables 是 iris 数据(150 行)的单个副本,iris 数据集 4,502 次(675,300 行),iris 数据集 450,200 次(6,753,000 行)。以下是相同顺序的结果。

Unit: milliseconds
    expr        min         lq      mean     median        uq       max neval cld
     sys 213.758862 216.612667 223.37484 217.858642 218.88561 342.42205   100   b
 RSQLite   6.981669   7.663255  10.08729   9.377483  10.90106  25.52816   100  a 

Unit: seconds
    expr       min        lq      mean    median        uq       max neval cld
     sys 10.633965 11.788077 12.844148 12.967207 13.757598 16.142357   100   b
 RSQLite  5.164632  6.791199  7.172043  7.351825  7.728878  8.486433   100  a 

Unit: seconds
    expr      min        lq      mean    median        uq       max neval cld
     sys 94.38379 101.36282 103.49785 102.98158 104.52018 114.95047   100   b
 RSQLite 48.48948  50.28782  53.18634  53.64562  55.80938  63.87987   100  a 

所以在我的笔记本电脑上,使用 RSQLitewrite.csv 总是快很多。

在超级计算机上,行数分别为 150、900,000 和 9,000,000,命令为

microbenchmark(
  sys = {system('sqlite3 -header -csv C:/Users/jmc6538/Documents/testing/test.sqlite "select * from iris;" > C:/Users/jmc6538/Documents/testing/test.csv')},
  RSQLite = {
    db <- dbConnect(RSQLite::SQLite(), "test.sqlite")
    result <- dbSendQuery(db, sql)
    write.csv(dbFetch(result), "./test2.csv")
    dbClearResult(result)
    dbDisconnect(db)
  })

和结果。

在超级计算机上使用 system 调用对于较大的 tables 更快,但对于较小的 table。

编辑: 在超级计算机上使用 data.tablefwrite 编写 CSV 比 shell 方法加速了 RSQLite 方法。我在这里只为 900,000 和 9,000,000 重复了 10 次table,因为我不想等到 100 次。如果人们追求速度,我认为这是更好的方法。