【问题标题】:Why does dbClearResult() take so long?为什么 dbClearResult() 需要这么长时间?
【发布时间】:2019-09-03 09:44:35
【问题描述】:

我很困惑为什么通过 MySQLConnect() 执行一个简单的查询需要这么长时间 我有一个 MySQL 数据库 ncol = 25 和 nrow = 10000 是一个小型数据库,我想使用 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

【问题讨论】:

  • but it's always take a lot of time ...这个脚本实际花费了多少时间,你为什么对它感到惊讶?
  • 可能 10 分钟或更长时间,我使用 SELECT * FROM TABLE LIMIT 1000 1-2 秒

标签: r


【解决方案1】:

我在这里看到了几个问题。通过在dbfetch 中使用n,您实际上是在运行完整的选择语句,然后只是拉回前n 行。我会尝试将 N 作为 SQL 的一部分粘贴,然后使用dbGetQuery,因为它需要您的代码的 2 个步骤并且可能更快。

也不要将结果保存为名为@9​​87654324@ 的变量,因为它已经是一个函数。给你:

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)

  }

【讨论】:

  • 没问题,如果是请考虑采纳答案
【解决方案2】:

很多时候,人们忘记了 R 默认会尝试将整个数据帧加载到计算机的内存中,这对于大型表来说是个大问题。

在您的示例中,您期望时间线性(1k 条记录:1-2 秒 :: 10k 条记录:10-20 秒),但是您可能没有考虑到 10k 条记录可能不适合您计算机的可用物理记忆。

这就是内存交换出现的时候,通常会造成严重破坏。

通常情况下,感觉就像您的计算机死机一样,即使几乎没有处理(例如,通过htop linux 命令的眼镜),因为操作系统很少发出内存交换信号。

因此,您的表可能已经在您的计算机中(即,在 R 本身下面的连接层中)并且瓶颈发生在 R 试图阻塞充满数据的内存的那一刻,同时它也开始减慢一切:从您的服务器接收更多数据,对您与鼠标和键盘的交互做出反应。因此,您可以登录到 SQL 服务器的监视器并立即终止查询,因为它不依赖于 R 监听您然后响应。

如果你足够好奇,可以尝试使用microbenchmark 包,根据批量大小的函数制作处理时间的响应曲线,以发现线性何时失效。

可用的解决方案:

  • 在本地下载完整表并在本地工作
    • 如果需要,可以并行处理
    • 使用大数据集包:bigmemory,data.table
  • 发现您的 bootleneck 批量大小并相应地处理大批量大小
    • dbFetch()ing 块并处理它们

【讨论】:

    【解决方案3】:

    最终代码

    
    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)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 2011-08-27
      • 2011-12-07
      • 2021-11-27
      • 2015-07-19
      相关资源
      最近更新 更多