我一直能够重现Coldfusion 10查询SQL Server 2008 R2的参数化性能问题,并且很想知道其他人得到了什么结果。下面是代码。
测试在创建一个具有100行的表,其中一个数据列除外,其余都为空白。然后运行Coldfusion查询10次,一半使用cfqueryparam,一半使用简单字符串。它返回每个响应时间的列表。当我运行这个测试时,除了最初的调用之外,参数化查询的运行速度要慢得多(大约是10-100倍)。
在SQL Server中发生了什么?
我在SQL server中看不出任何区别。在两种情况下,计划缓存显示几乎相同的计划(一个显然是参数化的),而Profiler显示两者的响应速度快。但是,Coldfusion无法处理参数化查询。
如何解决这个问题?
奇怪的是,如果将varchar更改为nvarchar,则问题会消失。或者如果将非空设置为开始,则两个响应速度都很慢(难以理解)。如果所有记录都为空白或非空,则再次没有问题。这必须是混合的。我无法在CF9中重现此问题,但尚未尝试CF11。
测试在创建一个具有100行的表,其中一个数据列除外,其余都为空白。然后运行Coldfusion查询10次,一半使用cfqueryparam,一半使用简单字符串。它返回每个响应时间的列表。当我运行这个测试时,除了最初的调用之外,参数化查询的运行速度要慢得多(大约是10-100倍)。
在SQL Server中发生了什么?
我在SQL server中看不出任何区别。在两种情况下,计划缓存显示几乎相同的计划(一个显然是参数化的),而Profiler显示两者的响应速度快。但是,Coldfusion无法处理参数化查询。
如何解决这个问题?
奇怪的是,如果将varchar更改为nvarchar,则问题会消失。或者如果将非空设置为开始,则两个响应速度都很慢(难以理解)。如果所有记录都为空白或非空,则再次没有问题。这必须是混合的。我无法在CF9中重现此问题,但尚未尝试CF11。
<cfset datasource="yourdatasource" />
<cfquery name="createdata" datasource="#datasource#">
--EMPTY PREVIOUS TESTS
IF OBJECT_ID('aaatest', 'U') IS NOT NULL
BEGIN
TRUNCATE TABLE aaatest;
DROP TABLE aaatest;
END
--CREATE TABLE TO CONTAIN DATA
CREATE TABLE [dbo].[aaatest](
[id] [int] NOT NULL,
[somedata] [varchar](max) NULL,
[somekey] [int] NOT NULL
) ON [PRIMARY];
--INSERT 100 ROWS WITH 99 BLANK AND 1 NON-BLANK
WITH datatable AS (
SELECT 1 id
UNION all
SELECT id + 1
FROM datatable
WHERE id + 1 <= 100
)
INSERT INTO aaatest(id,somekey,somedata)
SELECT id,1,case when id=99 then 'A' else '' end
FROM datatable;
</cfquery>
<cfset results=[] />
<cfloop from="1" to="10" index="n">
<!--- use parameters for every other test --->
<cfset useParameters = (n mod 2 is 0) />
<cfquery name="myquery" datasource="#datasource#" result="result">
SELECT somedata
FROM aaatest
WHERE somekey=
<cfif useParameters>
<cfqueryparam value="1" CFSQLType="CF_SQL_INTEGER" />
<cfelse>
1
</cfif>
</cfquery>
<!--- store results with parameter test marked with a P --->
<cfset arrayAppend(results,(useParameters?'P':'')&result.executiontime) />
</cfloop>
<cfdump var="#results#" />
cf_sql_numeric
。这似乎可以使测试速度更快。顺便问一下,你如何从SQL Server中读取计划缓存? - Bernhard Döbler