【问题标题】:Go prepared statements vs querying directlyGo 准备好的语句 vs 直接查询
【发布时间】:2013-11-11 06:11:32
【问题描述】:

普遍的共识似乎是直接查询语句不允许参数,而准备语句允许。

但是在 Go 的 database/sql 包中,您可以使用 ODBC 参数并将参数发送到诸如 db.QueryRow() 和 db.Query() 之类的东西。所以看起来它们在功能上是等效的。

话虽如此,那么首先创建一个语句,然后执行它有什么意义呢?假设语句首先针对数据库进行编译——这不会增加负载并因此降低性能,因为您要添加额外的行程吗?既然你可以从 Query/QueryRow 中获取参数,那岂不是让语句成为一件坏事?

【问题讨论】:

    标签: go odbc


    【解决方案1】:

    请记住,database/sql 包旨在涵盖所有理论上可能的 SQL 数据库系统的功能,而不会妨碍特定平台。

    SQL 驱动程序 实例在运行时通过sql.Register 注入。这些驱动程序不一定基于 ODBC,它可能是其他东西。

    有些 SQL 数据库支持转义查询参数,有些不支持 - 有些支持 “编译” 准备好的语句,有些不支持。

    通过将其设为两步过程,驱动程序可以决定在何处以及如何转义查询参数以及如何将它们插入到查询中。

    您可以使用 ODBC 参数并将参数发送到诸如 db.QueryRow() 和 db.Query() 之类的东西

    这些方法具有此签名只是为了方便,在后台驱动程序仍然单独转义和查询。你可以看到这种情况分别发生在herehere

    【讨论】:

      【解决方案2】:

      理论上,当数据库服务器接收到一个简单的 SQL 语句(或批处理)时,它必须对其进行编译:将其解析为某种内部形式,然后准备所谓的“查询计划”——操作顺序(例如索引或表扫描、比较等)来执行实际请求。做这一切显然会耗费一定的服务器资源。如此多的 DBMS 开始支持“准备好的语句”:服务器只执行一次解析/规划步骤,然后将“句柄”交给您随后多次“调用”的结果,只是提供不同的参数。

      现在让我们进入一个更复杂的领域。

      首先要注意的是,当内存和处理能力变得更便宜时,在商品到高端服务器上运行的 DBMS 能够在处理查询时花费更多资源,因此其中一些缓存 用户查询。也就是说,当您执行简单查询(SQL 语句或批处理)时,服务器会执行所有常见的解析/查询计划,但随后会保存结果,如果稍后遇到相同的查询,它会跳过处理部分并执行对数据进行操作。

      要注意的第二件事是,虽然编程语言/库倾向于为程序员提供某种通用接口来访问数据库引擎(C 的 ODBC 就是一个例子,database/sql因为Go 是另一个,还有无数其他),有线协议 或其他实际 访问服务器的方式可能会大不相同。例如,一台数据库服务器可能支持在其有线协议中与查询一起传递参数,而另一台可能不支持,因此访问层必须将您的参数转换为转义的 SQL 文字并将它们嵌入到查询中然后将其发送到服务器。

      您应该从中获得的主要思想是:数据库引擎是不同的,如果您计划通过您的程序对其施加大量负载,您必须了解自己的来龙去脉。了解您的 DMBS 的有线协议可以做什么和不能做什么,了解您的 DBMS 是否能够快速建立连接等等等等。查找有关特定 DBMS 性能优化的文档。

      另请参阅thisthis,了解有关不同 DBMS 的一些讨论。

      【讨论】:

        猜你喜欢
        • 2013-08-02
        • 2020-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-18
        • 1970-01-01
        • 2011-09-11
        • 1970-01-01
        相关资源
        最近更新 更多