【发布时间】:2017-07-19 14:54:03
【问题描述】:
我继承了一个数据库应用程序,该应用程序有一个包含大约 450 个查询的表。有一个调用程序将@QueryId 和@TheId 作为输入参数。执行这些查询的唯一方法是通过此过程。查询是这样的:
@sql = replace('insert into #temp select col1, col2, col3, col4
from SomeTable st join OtherTable ot on matching_column
where st.TheID = ##TheId##', '##TheId##', @TheId);
exec sp_executesql @sql;
我想获得计划重用,所以我将##TheId## 替换为@TheId,然后执行如下查询:
exec sp_executesql @sql, N'@TheId int', @TheId;
但是,即使@sql 字符串已经编译并在过程缓存中,我仍然看到每个计划都是唯一计划的相同行为。
现在字符串是这样的
...where where st.TheID = @TheId
问题:如何在参数化查询中根据需要获得计划重用?
【问题讨论】:
-
这不是参数化查询。通过建立一个字符串,您已经完全击败了这里的参数。您应该将参数传递给动态 sql,或者更好地避免使用动态 sql。从您发布的内容来看,这里根本不需要动态 sql。
-
不要使用动态 SQL。这不是参数化查询,它只是一个普通的字符串,像任何其他 SQL 字符串一样容易受到 SQL 注入的影响
-
这是一个很好的方法,因为它(更重要的是)解决了 SQL 注入问题。
-
我正在尝试修复过程缓存膨胀。有 450 条不同的规则,但它们每天要针对各种记录执行数千次。我昨晚看了看制作,看到了 50,000 多个不同的计划。我想将其减少到〜450。然后我可以调整表现不佳的人,看看哪些最昂贵,等等。我不能用 50,000 个查询来做到这一点
-
每个不同计划的 sql 文本是否完全相同?
标签: sql-server sql-execution-plan sp-executesql