gpt4 book ai didi

go - 在go中优化SQL数据访问

转载 作者:IT王子 更新时间:2023-10-29 01:47:35 24 4
gpt4 key购买 nike

我正在尝试将我一直在使用的 API 实现从 GORM ORM 库切换到 SQLx,以提高数据访问效率。特别是,我试图摆脱一些 SELECT N+1 问题。所以,我有一个网站有帖子的一对多关系。我正在实现的 API 返回一个站点列表作为 JSON 对象,每个站点都有一个嵌套的 posts 列表。结构看起来有点像这样

{    "sites": [        {            "id": 1,            "name": "Site #1",            "posts" [                {"title": "Post #1", "published": "1/2/2000", ... },                {"title": "Post #2", "published": "1/3/2000", ... },                ... more posts ...            ]        },        {            "id": 2,            "name": "Site #2",            "posts": [                 ... post list for site #2 ...            ]        }        ... more sites ...   ]}

这在 GORM 中很容易实现,但是当我查看正在运行的 SQL GORM 来实现它时,我意识到它正在从列表中的每个站点的帖子中进行选择。所以我试图像这样使用 SQL 来避免 N+1 问题。

SELECT s.id, s.name, p.title, p.published FROM sites as s, posts as p WHERE p.site_id = s.id

这让我在单个查询中获得了我需要的所有数据。但是我对如何将所有这些扫描到站点结构列表中有些困惑。在 GORM 中,我定义了以下结构(为简洁起见进行了简化)

type struct Post {    Id        uint      `json:"-"`    Title     string    Published time.Time    SiteId    uint      `json:"-"`    Site      Site      `json:"-"`}type struct Site {    Id   uint    Name string}

然后我会做类似的事情

var sites []Siteresult := db.Preload('Posts').Find(&sites)if result.Error != nil {    ... error handling ...} else {   operate on sites here}

所以问题是,如何使用 SQLx 将我的新 SQL 扫描到结构 slice 中,从而产生与 GORM 生成的数据结构类似的数据结构?我不介意编写自己的扫描器,但我仍然希望能够使用 SQLx Select()Get() 方法。我需要做什么才能完成这项工作?

var sites []Siteerr := db.Select(query, &sites) // where query is SQL from above

编辑:似乎如果我执行我在这个问题中给出的确切代码,GORM 实际上不会执行 N+1 选择,它会运行两个查询,一个用于站点的简单 SELECT 和一个SELECT ... WHERE ... IN ... for posts 然后整理两个结果集。不过,我仍然想知道如何在 SQLx 中执行此操作。

最佳答案

这可能不是答案,但对于评论来说太长了。

如果您仍在使用 GORM,则可以创建自定义 SQL。请参阅文档:http://jinzhu.me/gorm/advanced.html#sql-builder

对你来说可能是这样的:

// Scan

type struct Post {
Id uint `json:"-"`
Title string
SiteId uint `json:"-"`
Site Site `json:"-"`
}

var result Post

db.Raw("
SELECT s.id, s.name, p.title, p.published
FROM sites as s, posts as p
WHERE p.site_id = s.id").Scan(&result)

关于go - 在go中优化SQL数据访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42815331/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com