从应用程序

时间:2016-03-21 09:55:33

标签: sql-server-2008 tsql query-optimization sql-execution-plan

我们正在研究SQL Server 2008.Java Web应用程序用作前端。

从应用程序触发的每个查询都作为存储过程执行,如查询#1中所示。

我们观察到,从应用程序执行计划执行简单SELECTUPDATE查询是不同的。

查询#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,因此查询响应时间很差。

对于如何解决此问题的任何建议表示赞赏。

2 个答案:

答案 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传递时创建了此问题。我们推荐了以下博客

https://blogs.msdn.microsoft.com/sqlcat/2010/04/05/character-data-type-conversion-when-using-sql-server-jdbc-drivers/