如何在不牺牲便利性的情况下提高数据库查询功能的速度

时间:2018-05-15 15:51:13

标签: r database performance

我写了一个函数来更方便地访问我在工作中使用的数据库:而不是需要输入传统的SQL命令,我只能在数据库中列出一个表的名称,该函数会自动将整个表加载到R,我分配给一个数据帧。加载时,某些类型 date logical 的列显示为 integer character ,所以我的功能也识别并重新铸造它们。

不幸的是,最近我的查询运行速度变慢了,有些甚至还没完成。我不知道这是因为数据库问题还是代码问题,但我只能控制后者,所以我想我会得到一些反馈并找出是否可以使某些部分更有效率。我知道的一部分效率不高是查询的*部分 - 我很少需要每一列,但我经常不知道我需要提前哪些,因为有我可以加载许多不同的表,*是我知道的唯一选择语句将适用于所有这些表。不过,我对任何其他效率见解持开放态度。我将介绍这个功能:

GetFinderTable <- function(table) {
  if (missing(table))
    stop("ERROR: Table missing")
  if (!table %in% c(*table names*))
    stop("ERROR: Table not found in Finder Database")
  query <- "*"

该函数的第一部分执行基本错误检查,以确保表名存在并且是数据库中的表之一。我将*值赋给“查询” - 我考虑过扩展它以为这个变量提供其他列名,但这将非常依赖于表。

  LoadPackages(c('DBI', 'RMySQL', 'glue', 'magrittr', 'rlist'))
  db <- dbConnect(MySQL(), user = -private-, password = -private-, host = -private-, dbname = -private-)
  df <- dbGetQuery(db, glue('select {query} from {table}'))
  dbDisconnect(db)

LoadPackages 是我为简化包管理而编写的另一个自定义函数 - 它将根据需要安装,更新或附加列出的包。无论谁运行此脚本,都将安装必要的软件包。接下来的三行实际上是在查询数据库。我使用 glue 因为它更方便,但我想知道与 paste 相比效率是否低。

  cols <- apply(df, 2, function(x) (grepl("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$", na.omit(x)) %>% all)) 
  %>% which
  size <- length(cols)
  if (size > 0) {
    if (size == 1)
      df[,cols] %<>% as.Date
    else
      df[,cols] %<>% lapply(as.Date)
  }
  cols <- apply(df, 2, function(x) (grepl("^[0-1]$", na.omit(x)) %>% all)) %>% which %>% 
    list.append(apply(df, 2, function(x) (grepl("False|True", na.omit(x)) %>% all)) %>% which)
  size <- length(cols)
  if (size > 0) {
    if (size == 1)
      df[,cols] %<>% as.logical
    else
      df[,cols] %<>% lapply(as.logical)
   }
  return(df) 
}

这是我希望提高效率的地方。接下来的几行隔离日期列(通过检查它们是否与R的日期格式匹配)和逻辑列(通过查看列是否仅包含0和1或“True”和“False”)。我偶然发现使用lapply的危险,只有一列需要重铸,因此为什么我有 if 条件。重铸后,将返回数据帧。

非常感谢任何有关如何提高功能效率的见解。我花了太长时间等待这些查询完成!

0 个答案:

没有答案