我们正在研究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,因此查询响应时间很差。
对于如何解决此问题的任何建议表示赞赏。
答案 0 :(得分:0)
是的,有一个问题,当我们切换到在存储过程中使用参数时,SQL Server无法有效使用过滤的索引。要解决此问题,一种方法是使用索引提示,如
SELECT * FROM <Table> WITH (INDEX(<indexName>))
但为此,我们必须继续使用相同的索引名称
其他方法是使用字符串连接,即强制SQL Server查看文字值(参数)
e.g。
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;
访问此网址 - https://www.brentozar.com/archive/2013/11/filtered-indexes-and-dynamic-sql/
答案 1 :(得分:0)
通过将nvarchar更改为varchar有助于获得性能优势(索引扫描到索引搜索)。此外,由于JDBC在将参数作为nvarchar而不是varchar传递时创建了此问题。我们推荐了以下博客