共同的共识似乎是直接查询的语句不允许参数,并且准备好的语句可以。
但是在Go的数据库/ sql包中,您可以使用ODBC参数并将参数发送到db.QueryRow()和db.Query()等内容。所以看起来它们在功能上是等价的。
话虽如此,那么首先创建一个语句然后执行它的重点是什么?假设语句首先针对数据库进行编译 - 这不会增加负载,从而降低性能,因为您要添加额外的行程吗?既然你可以从Query / QueryRow获取参数,那么这不会使语句变坏吗?
答案 0 :(得分:4)
请记住,database/sql
包是一个包,旨在涵盖所有理论上可能的SQL数据库系统的功能,而不会妨碍特定于平台的方式。
SQL 驱动程序实例在运行时通过sql.Register
注入。这些驱动程序不一定构建在ODBC上,它可能是其他东西。
有些SQL数据库支持转义查询参数,有些则不支持 - 有些支持“编译”准备好的语句,有些则不支持。
通过使其分为两步,驱动程序可以决定在何处以及如何转义查询参数以及如何将它们插入到查询中。
您可以使用ODBC参数并将参数发送到db.QueryRow()和db.Query()
之类的内容
答案 1 :(得分:2)
理论上,当数据库服务器收到一个简单的SQL语句(或批处理)时,它必须编译它:将其解析为某种内部形式,然后准备所谓的“查询计划” - 操作序列(如索引或表扫描,比较等)来执行实际请求。这样做显然会耗费服务器资源。许多DBMS开始支持“预备语句”:服务器只执行一次解析/计划步骤,并将“手柄”移到您随后“多次”“调用”的结果上,只提供不同的参数。
现在让我们进入一个更复杂的领域。
首先要注意的是,当内存和处理能力变得更便宜时,运行商品到高端服务器的DBMS能够在处理查询时花费更多资源,因此其中一些缓存用户查询。也就是说,当您执行简单查询(SQL语句或批处理)时,服务器会执行所有常规的解析/查询计划,但随后会保存结果,如果稍后遇到相同的查询,则会跳过处理部分并执行对数据的操作。
第二点要注意的是,虽然编程语言/库倾向于为程序员提供一个用于访问数据库引擎的某个 common 接口(C
的ODBC就是一个例子,{ {1}} database/sql
是另一个,并且有无数其他人),有线协议或实际访问服务器的其他方式可能会有很大差异。例如,一个数据库服务器可能支持在其有线协议中传递参数以及查询,而另一个数据库服务器可能不支持,因此访问层必须将您的参数转换为转义的SQL文本并将它们嵌入到查询中然后将其发送到服务器。
您应该从这一切中获取的主要想法:数据库引擎是不同的如果您计划通过程序对其进行密集加载,则必须了解您的来龙去脉。了解DMBS的线路协议可以做什么以及它不能做什么,知道你的DBMS是否快速建立连接等等等。查找有关特定DBMS性能优化的文档。