从应用程序执行参数化查询时执行计划发生变化
Execution plan changes while executing parameterized query from application
我们正在开发 SQL Server 2008。Java Web 应用程序用作前端。
从应用程序触发的每个查询都作为存储过程执行,如查询 #1 所示。
我们在执行简单的 SELECT
和 UPDATE
查询时观察到来自应用程序执行计划的不同。
查询 #1 执行需要 3 秒:
declare @p1 int
exec sp_prepexec @p1 output, N'@P4 nvarchar(4000)',
N' SELECT KEY FROM dbo.DETAIL
WHERE KEY = @P4',N'SIND-60068635-R-202'
select @p1
查询 #2 的执行时间不到 1 秒:
SELECT KEY
FROM DETAIL
WHERE KEY = 'SIND-60068635-R-202'
我们观察到两个查询的执行计划不同。对于第二个查询,正在应用在 KEY
上创建的索引,因此查询响应良好,但同一索引未用于查询 #1,因此查询响应时间很差。
如有任何解决此问题的建议,我们将不胜感激。
是的,有一个问题,当我们切换到使用存储过程中的参数时,SQL服务器无法有效地使用过滤索引。要解决此问题,一种方法是使用
之类的索引提示
SELECT * FROM <Table> WITH (INDEX(<indexName>))
但为此我们必须继续使用相同的索引名称
其他方法是使用字符串连接,即通过强制 SQL 服务器查看文字值(参数)
例如
DECLARE @sql AS NVARCHAR(MAX) = N'';
DECLARE @p1 AS VARCHAR(10)='test'
SET @sql += 'SELECT KEY FROM dbo.DETAIL WHERE KEY = ' + CAST(@p1 AS NVARCHAR(10));
EXEC sp_executesql @sql;
访问这个url
- https://www.brentozar.com/archive/2013/11/filtered-indexes-and-dynamic-sql/
通过将 nvarchar 更改为 varchar 有助于获得性能优势(索引扫描到索引查找)。此外,JDBC 在将参数作为 nvarchar 而不是 varchar 传递时会产生此问题。我们参考了以下博客
我们正在开发 SQL Server 2008。Java Web 应用程序用作前端。
从应用程序触发的每个查询都作为存储过程执行,如查询 #1 所示。
我们在执行简单的 SELECT
和 UPDATE
查询时观察到来自应用程序执行计划的不同。
查询 #1 执行需要 3 秒:
declare @p1 int
exec sp_prepexec @p1 output, N'@P4 nvarchar(4000)',
N' SELECT KEY FROM dbo.DETAIL
WHERE KEY = @P4',N'SIND-60068635-R-202'
select @p1
查询 #2 的执行时间不到 1 秒:
SELECT KEY
FROM DETAIL
WHERE KEY = 'SIND-60068635-R-202'
我们观察到两个查询的执行计划不同。对于第二个查询,正在应用在 KEY
上创建的索引,因此查询响应良好,但同一索引未用于查询 #1,因此查询响应时间很差。
如有任何解决此问题的建议,我们将不胜感激。
是的,有一个问题,当我们切换到使用存储过程中的参数时,SQL服务器无法有效地使用过滤索引。要解决此问题,一种方法是使用
之类的索引提示SELECT * FROM <Table> WITH (INDEX(<indexName>))
但为此我们必须继续使用相同的索引名称
其他方法是使用字符串连接,即通过强制 SQL 服务器查看文字值(参数)
例如
DECLARE @sql AS NVARCHAR(MAX) = N'';
DECLARE @p1 AS VARCHAR(10)='test'
SET @sql += 'SELECT KEY FROM dbo.DETAIL WHERE KEY = ' + CAST(@p1 AS NVARCHAR(10));
EXEC sp_executesql @sql;
访问这个url - https://www.brentozar.com/archive/2013/11/filtered-indexes-and-dynamic-sql/
通过将 nvarchar 更改为 varchar 有助于获得性能优势(索引扫描到索引查找)。此外,JDBC 在将参数作为 nvarchar 而不是 varchar 传递时会产生此问题。我们参考了以下博客