常见的咒语是总是更喜欢PreparedStatement
而不是Statement
,因为它可以防止SQL注入和(显着)性能提升。
但是如果我的代码一遍又一遍地重建相同的PreparedStatement
,而不是正确地重用它呢?
使用Statement
的某些性能优势是否仍然存在,或者我是否为字符串参数留下了重量级引用转义引擎?
答案 0 :(得分:1)
在Statement上重建PreparedStatement仍然有好处,但它将取决于供应商。例如,在Oracle中,使用绑定变量是一种很好的做法,以便不破坏服务器的sql缓存。
Oracle服务器将获取sql字符串的哈希,以查看它是否已存在于Oracle服务器的sql缓存中。如果是这样,则可以重用该语句的缓存pcode。在这种情况下,许多工作(如解析,验证,检查授权等)已经完成,只需要更新参数区域。此外,由于不需要将新语句放在那里,因此将最小化sql缓存的使用。
在设计不佳的应用程序中,我们会看到sql缓存中包含如下语句:
SELECT wage FROM employee WHERE employee_id = 1
SELECT wage FROM employee WHERE employee_id = 2
SELECT wage FROM employee WHERE employee_id = 3
SELECT wage FROM employee WHERE employee_id = 4
从客户端收到的语句不会导致sql缓存中的缓存命中,因此需要再次完成所有解析工作并将新语句添加到缓存中。不仅有解析语句的额外工作,而且缓存变得无用,因为它充斥着这些东西。在设计良好的应用程序中,您可以调整sql缓存的大小,使应用程序运行的每个语句在预热后都位于缓存中。
我们会查询字典表,计算具有类似前缀的语句来查找这些违规者,获取应用程序代码以使用绑定参数(如果是Java代码,则要求开发人员使用PreparedStatements)。然后我们会在缓存中看到这样的语句:
SELECT wage FROM employee WHERE employee_id = :1
单一陈述。如果客户端一次又一次地重建它作为Prepared语句,如果它出现在相同的缓存命中,则无关紧要。