Sql server 2008 具有Select TOP(n)的不同SQL查询计划
我试图查看一个简单的select Top(n)的查询计划。每次我更改n(我获得的记录数)时,查询计划都会更改,选择前10个会导致性能问题,小于10或大于10时,查询将平稳运行 如果实体框架(4.2)有所不同,则会生成查询 查询是:Sql server 2008 具有Select TOP(n)的不同SQL查询计划,sql-server-2008,Sql Server 2008,我试图查看一个简单的select Top(n)的查询计划。每次我更改n(我获得的记录数)时,查询计划都会更改,选择前10个会导致性能问题,小于10或大于10时,查询将平稳运行 如果实体框架(4.2)有所不同,则会生成查询 查询是: exec sp_executesql N'SELECT TOP (10) [Project1].[Id] AS [Id], [Project1].[DateReceived] AS [DateReceived], [Project1].[Status] AS
exec sp_executesql N'SELECT TOP (10)
[Project1].[Id] AS [Id],
[Project1].[DateReceived] AS [DateReceived],
[Project1].[Status] AS [Status],
[Project1].[Subject] AS [Subject],
[Project1].[Description] AS [Description],
[Project1].[Path] AS [Path],
[Project1].[C1] AS [C1],
[Project1].[C2] AS [C2],
[Project1].[C3] AS [C3],
.
.
.
.
.
.
.
WHERE [Project1].[row_number] > 0
ORDER BY [Project1].[DateReceived] DESC',N'@p__linq__0 int,@p__linq__1 int,@p__linq__2 datetime2(7),@p__linq__3 datetime2(7),@p__linq__4 nvarchar(4000),@p__linq__5 nvarchar(4000),@p__linq__6 nvarchar(4000),@p__linq__7 nvarchar(4000)',@p__linq__0=-1,@p__linq__1=-1,@p__linq__2='2013-03-15 00:00:00',@p__linq__3='2013-04-15 23:59:55',@p__linq__4=N'ALL',@p__linq__5=N'ALL',@p__linq__6=N'',@p__linq__7=N'%%'
为什么前10名会导致性能问题
我还无法共享图像,以下是链接:
正如@JanDrozen所说,这很可能是一个统计问题。当数据大小超过某个阈值时,生成的执行计划不再是最佳计划,但统计信息不允许它获得正确的估计行数。优化器并不总是生成最佳执行计划。这是一个令人印象深刻的编程成就壮举,通常是从我们的谷壳中获取黄金,但它实际上只能凭借手头的数据尽其所能。它使用肉欲统计数据,并将使用估计的结果集大小来确定它认为最好的计划 在不首先更新统计数据的情况下判断这是否是统计数据问题的一种方法是启用实际执行计划,并查看属性 检查:
- 如果数据进入管道,则表明估计的行数接近实际行数
- 执行计划的属性表示优化器得出了最优计划。在属性中,它将告诉您选择该计划的原因。有时候,如果统计数据已经过时,那么优化器永远也找不到最佳计划,只能使用它所能找到的最佳计划
USE AdventureWorks2012;
GO
UPDATE STATISTICS Production.Product(Products)
WITH FULLSCAN, NORECOMPUTE;
GO
有一个存储过程sp_updatestats[[@resample=]'resample']
但是我从来没有用它获得过很好的结果,我也从来没有强迫它用完整的扫描进行更新,这是我获得好的统计数据的最好方法
如果您需要对大量表执行此操作,那么这里有一个我以前使用过的脚本,用于使用动态sql重新生成统计数据
DECLARE @sql nvarchar(MAX);
SELECT @sql = (SELECT 'UPDATE STATISTICS ' +
quotename(s.name) + '.' + quotename(o.name) +
' WITH FULLSCAN; ' AS [text()]
FROM sys.objects o
JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE o.type = 'U'
FOR XML PATH(''), TYPE).value('.', 'nvarchar(MAX)');
PRINT @sql
EXEC (@sql)
这是一篇关于统计的好文章,对它们是什么、它们做什么以及如何看待它们进行了很好的细分。你的问题是什么?你能把执行计划也张贴出来吗?这会很有帮助的。我的第一个想法是:SQL Server使用其统计信息更改其执行计划。您可以假设更新统计信息。执行计划已添加到我的上述问题中。@NEO1540:将这些执行计划作为XML发布到。