为什么dbClearResult()需要这么长时间?

时间:2019-09-03 09:44:35

标签: r

我困惑为什么通过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

3 个答案:

答案 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程序包以批处理函数的形式绘制处理时间的响应曲线,以发现线性下降的时间。

可用的解决方案:

  • 在本地下载完整表并在本地工作
    • 根据需要并行处理
    • 使用大数据集数据包:bigmemorydata.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)
}