我正在使用 .NET TableAdapter 在我的应用程序中执行 SELECT 查询,如下所示。问题是这种类型的查询有时需要几分钟才能执行。然而,当我在 SQL Server 中测试它时,它会立即返回结果。(这样做SET ARITHABORT ON/OFF
有时OPTION(RECOMPILE)
可以解决问题,但并非总是如此。)
/*The query defined in the designer.cs*/
SELECT Column1, Column2, Column3...
FROM MyTable
WHERE column1 = @var1 AND column2 = @var2
如果我删除变量以使用文字,它会修复速度。
SELECT Column1, Column2, Column3...
FROM MyTable
WHERE column1 = 'Billing' AND column2 = 'New'
使用SqlCommand.ExecuteReader()
效果并不好。我认为它仍然将参数作为单独的变量发送,以供 SQL Server 处理。
最后,我尝试在SQL Server中使用变量,但它并没有减慢任何速度。因此,我想知道使用变量是否确实是问题所在。(在发送查询之前不应该TableAdapter
用文字替换变量吗?)
DECLARE @status va1= 'Billing'
DECLARE @status var2= 'New'
SELECT Column1, Column2, Column3...
FROM MyTable
WHERE column1 = @var1 AND column2 = @var2
有没有办法在不将所有带有变量的查询更改为文字的情况下修复性能?
当您在查询中使用 @var1 和 @var2 等变量时,SQL Server 必须生成一个考虑这些变量的潜在值的查询执行计划。SQL Server 尝试创建适合各种参数值的计划。在某些情况下,此过程可能会导致执行计划不理想,尤其是当表中的数据分布不均匀时。
另一方面,当您在查询中使用“Billing”和“New”等文字时,SQL Server 可以生成特定于这些常量值的查询执行计划。这可以产生更有效的执行计划,因为它不必考虑不同的可能值。
我的建议;
确保查询中涉及的列的统计信息是最新的。过时的统计信息可能会导致查询计划不理想。您可以使用 UPDATE STATISTICS 命令更新特定表和列的统计信息。
您还可以使用 DBCC FREEPROCCACHE 清除特定查询的缓存,但请谨慎使用,因为它会影响整体服务器性能。缓存的查询计划可能会降低效率。