奇怪的 Coldfusion cfqueryparam

Weird Coldfusion cfqueryparam

SELECT  DISTINCT Table3.ID 
FROM    Table1 
          INNER JOIN Table2 ON Table1.thisID = Table2.thisID 
          INNER JOIN Table3 ON Table2.ID = Table3.ID 
WHERE ( Table1.ID IN 
         ( 
            <cfqueryparam cfsqltype="cf_sql_integer" 
                value="#idlist#" list="yes">
         )
      ) 
AND   Table2.ID IN 
      (  
           <cfqueryparam cfsqltype="cf_sql_integer" 
                 value="#idlist2#" list="yes">
      ) 
AND  Table3.active=1 
ORDER BY Table3.ID

当我 运行 上面的代码需要 11 到 15 秒。如果我删除 cfqueryparam,只使用 idlist2 变量,查询只需要 32 毫秒。

这是 cfqueryparam 的问题,还是我做错了什么?

SQL 性能会因 IN 子句中的长列表而急剧下降。如果您可以减少列表的长度,您的查询性能可能会提高。

当您使用 cfqueryparam 时,值将作为 arguments/parameters/variables 的列表传递给 SQL。当您不使用 cfqueryparam 时,值列表被硬编码到查询字符串中。这允许 SQL 的 "query execution plan" 针对特定的值列表进行预优化。它还允许将计划从一次执行缓存到下一次执行。这会导致后续 相同 查询执行得非常快,就像在调试和测试期间一样。

如果这是一个动态查询,如果值列表在每次查询时都发生变化 运行,那么您要确保使用 cfqueryparam 以便 SQL 服务器不缓存每个一次性硬编码查询的执行计划。

此外,cfqueryparam 为您提供了很多针对 SQL Injection attacks 的保护。从安全方面来说,我建议传递到查询中的 all 值应该使用 cfqueryparam.

最后,尝试 运行 在 SQL Server Management Studio 中查询并单击 Show Actual Execution Plan 按钮。它可以帮助您确定在表上添加一个或多个索引是否有助于缩短执行时间。
'Missing Index' feature of SQL Server Management Studio