我有一个项目倾倒在我的腿上,而且我远远超出了我的元素。有一个表,大约有10,000,000行正在被查询。特别是有一个查询运行时间太长,并且超时。 Linq生成的查询是
-- Region Parameters
DECLARE @p0 Int = 335
DECLARE @p1 DateTime = DATEADD(day,-7,GETDATE())
-- EndRegion
SELECT *
FROM [Events] AS [t0],
[Devices] AS [t1],
[EventTypes] AS [t2],
[DeviceTypes] AS [t3]
WHERE ([t1].[DeviceID] = [t0].[DeviceID])
AND ([t2].[EventTypeID] = [t0].[EventTypeID])
AND ([t3].[DeviceTypeID] = [t1].[DeviceTypeID])
AND ([t1].[RoomID] = @p0)
AND ([t0].[EventTime] >= @p1)
如果我将最后一行更改为[t0].[EventTime] >= DATEADD(day,-7,GETDATE())
而不是使用变量@p1
,则查询从运行45秒到运行需要3秒。
我的两个问题是1)为什么这个简单的改变会如此大幅提升性能2)是否有办法迫使Linq不使用变量并内联datetime对象?
Linq代码是C#.NET 3.5,服务器是MSSQL 2005
编辑:为简洁起见,我添加了SELECT *,实际查询不会这样做。
答案 0 :(得分:3)
看到文字与参数的差异很常见
另一个选项是[t0]。[EventTime]是smalldatetime,你有数据类型优先级强制转换到datetime以匹配@ p1。通过直接使用DATEADD,优化器会将DATEADD表达式更改为smalldatetime
答案 1 :(得分:2)
如果我改变最后一行 [t0]。[EventTime]> = DATEADD(day,-7,GETDATE())而不是 使用变量@ p1,查询进行 从45秒开始跑到 花3秒钟跑。
我对这种说法很怀疑。你确定在交换后冲洗了缓冲区吗?您是否尝试过交换,使用@ p1 param时仍然表现不佳?
关于性能故障排除的一般说明。
执行计划为您提供了发展方向的总体方向,但并不总是准确的。将其与IO和CPU统计信息进行平衡。
答案 2 :(得分:2)
10.0.1600是SQL Server 2008 RTM。尝试升级到SP2(无论如何这都是个好主意!)。
通常当我遇到奇怪的优化问题时,我发现SQL Server已经过时,而较新的SP解决了这些问题。不总是,但经常。