我困惑为什么通过MySQLConnect()执行简单查询会花费这么长时间 我有一个MySQL数据库ncol = 25,nrow = 10000是一个samll数据库,我想使用MySQLConnect()获取一些数据帧,但是它总是要花费很多时间
dbClearResult(dbSendQuery) #take long time but why
dbDisconnect(DBConnect) #take long time but why
我检查了Intelnet,这很好,我使用SequelPro来确保速度很快。
这是完整的代码:
library("DBI")
library("RMySQL")
library("dplyr")
library("data.table")
MySQLConnect <- function(N=1000) {
DBConnect <- dbConnect(RMySQL::MySQL(),
user = "root",
password = "root",
dbname = "root",
host = "root",
port = 3306,
)
dbSendQuery <- dbSendQuery(DBConnect, "SELECT * FROM TABLE")
dbFetch <- dbFetch(dbSendQuery, n=N)
data.table <- data.table(dbFetch)
dbClearResult(dbSendQuery)
dbDisconnect(DBConnect)
return(data.table)
}
#platform x86_64-apple-darwin15.6.0
#arch x86_64
#os darwin15.6.0
#system x86_64, darwin15.6.0
#status
#major 3
#minor 6.1
#year 2019
#month 07
#day 05
#svn rev 76782
#language R
#version.string R version 3.6.1 (2019-07-05)
#nickname Action of the Toes
如果我发送了此邮件,可以立即断开连接
SHOW PROCESSLIST FOR SEARCH "SELECT * FROM TABLE" ID;
KILL THIS ID;
"Closing open result sets"
我该如何最好地执行此代码?
原因
dbSendQuery <- dbSendQuery(DBConnect, "SELECT * FROM TABLE") #it's not run end over so dbClearResult(dbSendQuery) and dbDisconnect(DBConnect) is waiting
答案 0 :(得分:0)
我在这里看到几个问题。通过在n
中使用dbfetch
,您实际上是在运行完整的select语句,然后仅撤回前n行。我会尝试将N粘贴为SQL的一部分,然后使用dbGetQuery
,因为它占用了代码的2个步骤,并且可能更快。
也不要将结果保存为名为data.table
的变量,因为它已经是一个函数。在这里,您去了:
MySQLConnect <- function(N=1000) {
DBConnect <- dbConnect(RMySQL::MySQL(),
user = "root",
password = "root",
dbname = "root",
host = "root",
port = 3306,
)
out <- dbGetQuery(DBConnect, paste0("SELECT * FROM TABLE LIMIT ", N))
dbDisconnect(DBConnect)
return(out)
}
答案 1 :(得分:0)
很多时候,人们常常忘记R默认情况下会尝试将整个数据帧加载到计算机的内存中,这对于大表是个大问题。
在您的示例中,您期望时间线性(1k条记录:1-2秒:: 10k条记录:10-20秒),但是您可能没有考虑到10k条记录可能不适合计算机的可用物理空间记忆。
那是内存交换进来的时候,通常会造成破坏。
通常,感觉到您的计算机处于冻结状态,即使几乎没有处理也没有处理(例如,通过htop
linux命令的眼镜查看),因为操作系统很少发出内存交换信号。
因此,您的表可能已经在您的计算机中(即,在R本身下面的连接层中),并且在R试图阻塞充满数据的内存的那一刻出现了瓶颈,同时它也开始降低了所有数据的速度:从您的服务器接收更多数据,并对您与鼠标和键盘的交互做出反应。因此,您可以登录到SQL Server的监视器并立即终止查询,因为它不依赖于R来监听您的内容,然后进行响应。
如果您有足够的好奇心,可以尝试使用microbenchmark
程序包以批处理函数的形式绘制处理时间的响应曲线,以发现线性下降的时间。
可用的解决方案:
bigmemory
,data.table
dbFetch()
分割大块并对其进行处理答案 2 :(得分:0)
最终代码
GetPlayerBroadInfo <- function(LIMIT = NULL) {
dbConnect <- DBI::dbConnect(
RMySQL::MySQL(),
host = "root,
dbname = "root",
user = "root",
password = "rootroot",
port = 3306,
":memory:"
)
dbQuery <- "
SELECT * FROM TABLENAME
"
dbGetQuery <- DBI::dbGetQuery(dbConnect,dbQuery)
return(dbGetQuery)
DBI::dbClearResult(dbGetQuery)
DBI::dbDisconnect(dbGetQuery)
lapply(dbListConnections(MySQL()), dbDisconnect)
}