Gav*_*vin 40 sql-server performance sql-server-2008
我有一个视图,使用CTE从表中返回2个整数.如果我查询这样的视图,它会在不到一秒的时间内运行
SELECT * FROM view1 WHERE ID = 1
但是,如果我像这样查询视图需要4秒钟.
DECLARE @id INT = 1
SELECT * FROM View1 WHERE ID = @id
我检查了2个查询计划,第一个查询正在主表上执行Clustered index seek返回1个记录,然后将其余的视图查询应用于该结果集,其中第二个查询正在执行索引扫描,即返回大约3000条记录而不仅仅是我感兴趣的记录,然后过滤结果集.
有没有明显的东西我试图让第二个查询使用Index Seek而不是索引扫描.我正在使用SQL 2008,但我所做的任何事情都需要在SQL 2005上运行.起初我认为这是某种参数嗅探问题,但即使清除缓存,我也会得到相同的结果.
eri*_*len 42
可能是因为在参数的情况下,优化器无法知道该值不为null,因此需要创建一个计划,即使它返回正确的结果.如果您有SQL Server 2008 SP1,则可以尝试添加OPTION(RECOMPILE)到查询中.
您可以在查询中添加OPTIMIZE FOR 提示,例如
DECLARE @id INT = 1
SELECT * FROM View1 WHERE ID = @id OPTION (OPTIMIZE FOR (@ID = 1))
在我的例子中,数据库表列类型被定义为 VarChar,参数化查询参数类型被定义为 NVarChar,这CONVERT_IMPLICIT在实际执行计划中引入以在比较之前匹配数据类型,这是母猪性能的罪魁祸首,2 秒 vs 11 秒。只需更正参数类型即可使参数化查询与非参数化版本一样快。
一种可能的方法是使用CAST参数,如下所示:
SELECT ...
FROM ...
WHERE name = CAST(:name AS varchar)
希望这可以帮助有类似问题的人。
| 归档时间: | 
 | 
| 查看次数: | 22909 次 | 
| 最近记录: |