【问题标题】:Would I be better by using a prepared statement here?在这里使用准备好的语句会更好吗?
【发布时间】:2016-06-15 20:06:34
【问题描述】:

stillstruggle 了解 Go 中准备好的语句的好处/psql

假设我有一个结构

type Brand struct {
    Id        int        `json:"id,omitempty"`
    Name      string     `json:"name,omitempty"`
    Issued_at *time.Time `json:"issued_at,omitempty"`
}

还有一些表 brands,其中 id 是一个唯一字段。现在我想使用 id 从该表中检索元素。

我可以使用 QueryRow 编写以下函数。

func GetBrand1(id int) (Brand, error) {
    brand := Brand{}
    if err := Db.QueryRow("SELECT name, issued_at FROM brands WHERE id = $1", id).Scan(&brand.Name, &brand.Issued_at); err != nil {
        if err == sql.ErrNoRows {
            return brand, nil
        }

        return brand, err
    }

    brand.Id = id
    return brand, nil
}

我可以使用准备好的语句做同样的事情(我希望它是一样的):

func GetBrand2(id int) (Brand, error) {
    brand := Brand{}

    stmt, err := Db.Prepare("SELECT name, issued_at FROM brands WHERE id = $1")
    if err != nil {
        return brand, err
    }
    defer stmt.Close()

    rows, err := stmt.Query(id)
    if err != nil {
        return brand, err
    }
    defer rows.Close()

    for rows.Next() {
        rows.Scan(&brand.Name, &brand.Issued_at)
        brand.Id = id
        return brand, err
    }
    if err = rows.Err(); err != nil {
        return brand, err
    }

    return brand, err
}

现在在我的应用程序中,我计划多次执行GetBrand* 函数(使用不同的参数)。 Will 是其中一种实现比另一种更可取(就 sql-requests/memory/anything 而言)。或者他们俩都很糟糕,我最好做点别的。

我读过thisfollowed up link,我看到了:

db.Query() 实际上准备、执行和关闭一个准备好的 陈述。这是数据库的三个往返。如果你不是 小心,您可以将数据库交互次数增加三倍 应用使

但我认为第二种情况下的准备好的语句将在函数末尾删除。

【问题讨论】:

标签: go prepared-statement


【解决方案1】:

在这两个示例中,数据库开销大致相同。如果您要大量使用语句,请在更广泛的范围内准备一次,以便可重用。

您只需使用该模式对数据库进行一次往返。

【讨论】:

  • 有什么可以支持这个说法的。因为它现在的情况,与我在问题中所写的假设相同,我希望有一些可靠的来源来支持这个假设。
  • @SalvadorDali 根据您链接的文档 Query[Row] 只是准备语句,运行它,然后关闭它,对吗?在我看来,如果您准备该语句一次,然后不断运行相同的准备好的语句,那么您将减少往返次数接近 3。您的第一个和第二个示例与您做的事情大致相同在每次函数调用时创建一个新的预处理语句。
  • 看起来很合理。谢谢,+1
【解决方案2】:

如果您曾经将数据库与用户输入结合使用,则应始终事先准备语句。

否则,您将面临插入数据库的风险(前 SQL 插入)。

【讨论】:

  • 首先这并不能回答我的问题,带有参数 $1 的第二个 queryRow 也会为我准备语句,所以你的答案并不正确
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多