【问题标题】:Go-MySQL-Driver: Prepared Statements with Variable Query ParametersGo-MySQL-Driver:带有可变查询参数的预处理语句
【发布时间】:2015-07-14 15:39:19
【问题描述】:

我想在我的 Go 服务器上使用准备好的语句和 MySQL,但我不确定如何使它与未知数量的参数一起工作。一个端点允许用户发送一组 id,Go 将从数据库中选择与给定 id 匹配的对象。这个数组可以包含 1 到 20 个 id,那么我将如何构造一个准备好的语句来处理它呢?我看到的所有示例都要求您确切知道查询参数的数量。

我能想到的唯一(非常不可能的)选项是准备 20 条不同的 SELECT 语句,并使用与用户提交的 id 数量相匹配的语句 - 但这似乎是一个可怕的 hack。那时我什至会看到准备好的语句的性能优势吗?

我被困在这里,所以任何帮助将不胜感激!

【问题讨论】:

  • 你能展示一个你的选择语句的样本吗?另请参阅 this 帖子,该帖子可能会回答您的问题。

标签: mysql rest http go


【解决方案1】:

据我所知,没有任何 RDBMS 能够绑定未知数量的参数。永远不可能匹配具有未知数量的参数占位符的数组。这意味着没有将数组绑定到查询的智能方法,例如:

SELECT xxx FROM xxx WHERE xxx in (?,...,?)

这不是客户端驱动的限制,数据库服务器根本不支持。

有多种解决方法。

您可以使用 20 ? 创建查询,绑定您拥有的值,并通过 NULL 值完成绑定。它工作得很好,因为涉及 NULL 值的比较操作的特殊语义。像“field = ?”这样的条件当参数绑定到 NULL 值时,总是评估为 false,即使某些行匹配。假设您的数组中有 5 个值,数据库服务器将不得不处理 5 个提供的值,外加 15 个 NULL 值。忽略 NULL 值通常足够聪明

另一种解决方案是准备所有查询(每个查询都有不同数量的参数)。只有在最大参数数量有限的情况下才有意义。它适用于准备好的语句真正重要的数据库(例如 Oracle)。

就 MySQL 而言,使用准备好的语句的好处是非常有限的。请记住,准备好的语句仅在每个会话中维护,它们不会在会话之间共享。如果你有很多会话,它们会占用内存。另一方面,用 MySQL 解析语句不涉及太多开销(与其他一些数据库系统相反)。通常,生成大量准备好的语句来覆盖单个查询是不值得的。

请注意,一些 MySQL 驱动程序提供了准备好的语句接口,而它们在内部不使用 MySQL 协议的准备好的语句功能(同样,因为通常不值得这样做)。

还有一些其他的解决方案(比如依赖临时表),但它们只有在参数数量很大时才有意义。

【讨论】:

  • 很多有用的信息,谢谢。我发现 - 就像你提到的 - MySQL 准备好的语句仅限于一个特定的连接。我的 Go 服务器保留一个连接池并为每个传入请求分配不同的连接,所以我看不出准备好的语句在那里会有什么优势。 go-mysql-driver 文档没有指定,但是如果连接在释放回连接池时丢失了准备好的语句,则需要为每个传入请求重新准备 - 消除任何优势。跨度>
猜你喜欢
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
相关资源
最近更新 更多