3

我有一个 linq 查询需要 11 分钟才能针对 MSSQL server 2008 执行。我使用 MSSQL Profiler 来查找执行时间很长的查询,然后我将它单独运行到我的数据库中。

我还删除了所有参数并直接添加了值并运行了查询。执行时间不到 1 秒!

我搜索了一下,发现使用参数确实会影响性能,因为计划是在 where 子句的值已知之前编译的

由于 Linq to SQL 总是运行参数化 SQL,在这种情况下我可以做些什么来提高性能?

我还没有发现任何可以改进的关于索引的列。Inner Join 语句中的第一个表有 192 014 行,不带参数的 SQL 执行时间不到一秒。附上执行计划的截图。

编辑在屏幕截图下方。

这是 Linq 查询:

var criteria = CreateBaseCriteria();

var wordsGroup = from word in QueryExecutor.GetSearchWords()
                 join searchEntry in QueryExecutor.GetReportData(criteria) on (word.SearchID + 100000000) equals searchEntry.EventId
                  group searchEntry by word.SearchWord into wg
                  select new SearchAggregate
                  {
                      Value = wg.Key,
                      FirstTime = wg.Min(l => l.EventTime),
                      LastTime = wg.Max(l => l.EventTime),
                      AverageHits = wg.Average(l => l.NumberOfHits.HasValue ? l.NumberOfHits.Value : 0),
                      Count = wg.Count()
                  };

return wordsGroup.OrderByDescending(w => w.Count).Take(maxRows);

带参数查询的执行计划(linq to sql) 已知值查询的执行计划

编辑:这里的屏幕截图确实有点小。参数化 SQL 中只有 5 个参数。

编辑2:是带有参数@p0 的Inner Join 语句导致执行计划发生变化。当我只删除带有值本身的@p0 变量时,它会在不到一秒的时间内运行。如果此值在所有情况下都是恒定的(我必须对此进行调查),我可以做任何事情以使该值不会像参数一样被使用吗?

4

2 回答 2

0

建议您在查询计划上方创建一个绿色索引。先试试这个。

于 2013-11-04T09:36:19.000 回答
0

我找到了一种绕过这个语句的方法,这导致执行时间变长了:

on (word.SearchID + 100000000) equals searchEntry.EventId

我所做的是添加一个计算列[SearchIdUnique] AS ([SearchID]+(100000000))。然后我可以将我的 Linq 查询更改为:

on word.SearchIdUnique equals searchEntry.EventId

查询执行时间缩短到不到一秒,问题就解决了。

于 2013-11-04T14:06:13.113 回答