考虑以下内容:
<cfquery name="aQuery" datasource="#aSource#">
SELECT aColumn
FROM aTable
WHERE bColumn = <cfqueryparam value="#aVariable#" cfsqltype="#aSqlType#" />
AND cColumn = 'someConstant'
AND dColumn is null
</cfquery>
如果我更改
AND cColumn = 'someConstant'
至
AND cColumn = <cfqueryparam value="someConstant" cfsqltype="#aSqlType#" />
是否存在潜在的性能改进?是否有可能影响绩效?
如果我对AND dColumn is null
做同样的操作(使用cfqueryparam)会怎样?
我的发现没有定论。
如果它很重要,假设ColdFusion9和Oracle数据库11g。
编辑:
我只想重申一下,我询问的是专门用于常量和/或null值的cfqueryparam标记,以及性能调整(如果有的话)。
是否存在潜在的性能改进?
没有。当涉及变化的参数时,绑定变量最有用。如果没有它们,数据库将在每次查询参数更改时生成一个新的执行计划(这很昂贵)。绑定变量鼓励数据库缓存和重用单个执行计划,即使参数发生变化。这节省了编译成本,提高了性能。常量确实没有任何好处。由于该值从未更改,因此数据库将始终重用执行计划。所以没有太多理由在常数上使用它。
是否有可能影响绩效?
我看到过一些特殊情况,在这些情况下,对常量使用绑定变量实际上可能会降低性能。但这确实是根据具体情况而定的。
- http://decipherinfosys.wordpress.com/2007/04/02/scenario-for-using-a-constant-instead-of-a-bind-variable-in-an-oltp-system/
- http://www.houseoffusion.com/groups/cf-talk/thread.cfm/threadid:24110#121568
我不这么认为,因为您已经有了一个<cfqueryparam>
,这将把它变成一个准备好的语句,但我不确定。
使用查询参数有两个方面的帮助。
首先,它将保护您免受SQLI的攻击。它将添加一个保护级别,以确保参数中的数据符合预期。
其次,您将看到性能的提高。但是,增长取决于数据模式和索引。该参数将允许数据库缓存查询计划。这加快了查询执行的初始开销。查询越复杂,缓存查询计划就越重要。
此外,请确保where子句中的所有列都有覆盖索引,并且它们的顺序正确。如果没有,查询优化器可能会选择忽略索引,直接进行表扫描。