不是一个完整的答案,而是我迄今为止的研究细节,以防止人们追溯我的步骤。
超时似乎无法通过 dbplyr 控制
dbconnect
接受驱动程序和参数以传递给驱动程序(文档)dbConnect(drv, ...)
:.
- 对于某些连接类型,附加参数可以包括
timeout
. 这个问题有一个使用 Cassandra 的示例:con <- dbConnect(odbc::odbc(), "Cassandra (DSN)", timeout = 10)
.
- 但是,似乎不支持将 timeout 作为
bigquery
. 该文档列出了以下参数(project
, dataset
, billing
, page_size
, quiet
, use_legacy_sql
, bigint
),并指出当前忽略了其他参数。
dbplyr
因此,鉴于上述情况, R viaDBI
或连接似乎不太可能控制超时。
将查询拆分为多个较短的查询
虽然不是 OP 的偏好(评论明确),但这仍然是一个潜在的解决方案。我使用一种基于唯一 ID 列的过滤方法,使用包装函数来减少一些额外的混乱:
reconnect <- function(jj){
if(exists("connection"))
dbDisconnect(connection) # avoids multiple concurrent connections
print(paste0(as.character(Sys.time()),"-- modulo ",jj," begun")) # track progress
connection <- dbConnect(
bigrquery::bigquery(),
project = "your-gcp-project-id",
dataset = "dataset-name",
billing = billing
)
mytable <- tbl(connection, "mytable") %>%
filter(unique_id %% NUM_SUBSETS == jj) # filter to subset, requires unique_id
# assignment into the parent environment
assign("connection", connection, envir = parent.frame())
assign("mytable ", mytable , envir = parent.frame())
}
然后我们迭代如下:
## parameters
DEVELOPMENT_MODE = FALSE
NUM_SUBSETS = 50
## subset
modulo = if(DEVELOPMENT_MODE){ modulo = 0 # only one if development mode
} else { modulo = 0:(NUM_SUBSETS-1) # otherwise all of them
}
results = data.frame()
for(jj in modulo){
reconnect(jj)
these_results = mytable %>%
-- some heavy dplyr wrangling --
%>% collect()
results = rbind(results, these_results)
}
我DEVELOPER_MODE
在测试/开发时设置为 true,当我想要整个运行时设置为 false。
其他需要考虑的途径
- 检查是否可以在 bigquery 帐户中设置/控制超时(如果不能通过 R 控制)。
- 调查有多复杂
-- heavy dplyr wrangling here --
。因为 dbplyr 不能翻译非常高效的 sql 代码,所以在我的 SQL 服务器工作中,保存中间表已经缩短了我的运行时间。鉴于下载 10GB 应该比几个小时快得多,瓶颈可能是 bigquery 执行所有动态处理(并且最初的 20 秒执行是延迟评估)。此链接表明单次执行的持续时间有六小时限制。