【问题标题】:How to set fetch size in golang?如何在golang中设置获取大小?
【发布时间】:2019-09-06 07:32:55
【问题描述】:

我正在尝试从数据库加载一个庞大的数据集。

    func main() {
        db, err := sql.Open("mysql", "root:pass1@tcp(127.0.0.1:3306)/tuts")

        if err != nil {
            log.Print(err.Error())
        }
        defer db.Close()
        results, err := db.Query("SELECT id, name FROM tags")
        if err != nil {
            panic(err.Error()) 
        }

        for results.Next() {
            var tag Tag
            err = results.Scan(&tag.ID, &tag.Name)
            if err != nil {
                panic(err.Error()) 
            }

            log.Printf(tag.Name)
        }
}

程序是否一次性将所有记录加载到内存中?或者有没有办法指定提取大小,以便程序一次只加载 n 行?假设数据库中有百万行,我想每次获取 1000 条记录。

【问题讨论】:

  • select count(*) from tags 怎么样?然后SELECT id, name FROM tags LIMIT 100。 guru99.com/sqlite-query.html#4
  • 不,它不会将所有内容加载到内存中。它在调用 Next() 时根据需要获取数据。
  • @RickyA 是的,我们可以编写自定义逻辑。但我想知道是否有标准库中的选项。
  • @Peter 是否对数百万行匹配行的数据库进行了数百万次调用?
  • 您也应该添加defer results.Close(),并且您可以在循环外声明var tag Tag,并在循环内重复使用相同的变量

标签: go go-sqlite3


【解决方案1】:

这适用于单行和数百万行。大多数 SQL 实现在读取时都有批处理的概念。它们根据需要从磁盘加载数据,并根据需要保持 RAM 使用率低/恒定。

例如,如果您选择 1000 行。数据库可能会将前 100 行加载到 RAM。 当您调用Next() 时,例如当您到达第 50 行时,数据库会再抓取 100 行(例如第 100 到 201 行)。

【讨论】:

  • 我可能错了,但我认为 OP 是在询问程序(客户端)是否将其全部加载到内存中,而不是数据库是否将其全部加载到内存中。
  • 是的,程序正在使用数据库的功能。我所说的仍然有效。
  • 并非如此。您的回答是关于数据库将如何处理其内存,问题是关于客户端将如何处理其内存。这些很可能在不同的机器上运行,因此数据库对数据库主机上的内存的处理与客户端使用其自己主机上的内存的问题在很大程度上无关。
猜你喜欢
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 2016-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-14
相关资源
最近更新 更多