R在进行循环或串联时的性能非常慢

时间:2019-07-11 09:30:20

标签: r mongodb powerbi mongolite

我已经用R写过一段代码,它实际上将连接到管理mongo数据库,该数据库包含其他数据库的列表。然后,该循环遍历到每个数据库的连接,从每个数据库中提取结果(对于我的示例,这是大约35个数据库中的每个数据库约100万行),并创建一个包含所有结果的大框架,然后,我将使用瓶坯分析。

  

注意:我正在R中专门这样做,因为我想将其用作Power BI中的数据源。 Power BI计划的刷新现在仅适用于R脚本,而不适用于python,我需要在脚本中执行此操作,因为我需要它来动态连接并从许多数据库中提取数据。

这个问题是,它可以正常工作,但是从单个数据库中提取和操作数据却要花费15分钟以上的时间,这种缝隙太长了,因为基本上我在这里所做的就是从数据库中提取数据,添加在结果中增加一列,并将结果连接在一起。

当我提取数据并且不对数据执行任何操作时,所花费的时间要少得多

library(mongolite)

connectDB = function(database) {
  username = "user"
  password = "password"
  host = "host:port"
  # Using plain-text
  uri = sprintf("mongodb://%s:%s@%s/%s?authSource=admin", username, password, host, database)
  return(uri)
}

prepareData = function( object, selector, date = FALSE ) {
  if( !hasName(object, selector) ) {
    return( NA )
  }
  if( is.null( object[[selector]] ) ) {
    return( NA )
  }
  if( date ) {
    return ( as.character( object[[selector]] ) )
  }
  return( object[[selector]] )
}

databases = function() {
  table <- mongo( "databases", url = connectDB( 'management' ) )

  results <- table$iterate('{}', field = '{}')

  ids <- c()
  databaseNames <- c()

  while(!is.null(database <- databases$one())){
    ids <- c(ids, database$'_id')
    databaseNames <- c(databaseNames, database$'database'$'name')
  }
  databases = data.frame(
    ID = ids,
    DatabaseName = databaseNames
  )
  return(databases)
}

getUsers = function(databases) {
  # creating containers for each column in the table
  ids <- c()
  databaseIDs <- c()
  names <- c()
  createdAts <- c()
  updatedAts <- c()

  for (i in 1:nrow(databases)) {

    id = as.character(databases[i, 'ID'])
    databaseName = as.character(databases[i, 'DatabaseName'])

    users <- mongo('users', url = connectDB(databaseName))

    print(Sys.time())

    usersResults <- users$iterate('{}', field = '{}')

    while(!is.null(usersResult <- usersResults$one())){

      # selects data from user table

      ids <- c(ids, usersResult$'_id')

      databaseIDs <- c(databaseIDs, id)

      names <- c(names, prepareData( usersResult, 'name') )
      createdAts <- c(createdAts, prepareData( usersResult, 'created_at', TRUE) )
      updatedAts <- c(updatedAts, prepareData( usersResult, 'updated_at', TRUE) )
    }
    print(Sys.time())
    break
  }

  return (
    data.frame(
      #produce a table which pulls in the containers
      ID = ids,
      DatabaseID = databaseIDs,
      Name = names,
      CreatedAt = createdAts,
      UpdatedAt = updatedAts
    )
  )  
}

#run the script
users <- getUsers( databases())
  

注意:该脚本也已匿名化,我的实际用例不是针对用户的,这只是一个例子,但我希望达到相同的结果

     

注意:我也是R编程的新手,我的背景是Web开发,尤其是JavaScript,NodeJS和PHP。 R构建框架的方式对我来说是很陌生的,因为它以相反的方式缝合,而不是建立一列而不是建立一列,所以这也可能是缺乏理解

0 个答案:

没有答案