查询花费太长时间在LINQ中执行

时间:2015-05-21 15:13:19

标签: c# sql sql-server linq entity-framework

我编写了一个查询,该查询应该从一个表中获取所有行,并将子查询执行到第二个表,只从最近的记录中提取一个值。在 SQL Server 中,查询执行大约需要15秒,LINQ查询大约需要2分钟。有人可以帮我把SQL翻译成LINQ,我一定做错了。

SQL

SELECT  a.isrunning,
        worktype = (
                    SELECT TOP 1
                            w.worktype
                    FROM    dbo.workorder w WITH (NOLOCK)
                    WHERE   w.assetnum = a.assetnum
                    ORDER BY w.statusdate DESC
                   ),
        a.status,
        *
FROM    dbo.asset a WITH (NOLOCK)
WHERE   a.assetnum IN ('list', 'of', 'asset', 'numbers')

LINQ查询:

(
  from a in db.assets
  let wo = (
            from w in db.workorders
            where w.assetnum == a.assetnum
            orderby w.statusdate descending
            select w).FirstOrDefault()
   where aliasStrings.Contains(a.assetnum)
   select new AssetWithWorkType {
      ...
   }
);

3 个答案:

答案 0 :(得分:1)

建议在外键上使用索引。还包括过滤和排序子句的索引。所以我建议你创建以下3个索引:

CREATE NONCLUSTERED INDEX [IDX_workorder_statusdate] ON dbo.workorder(statusdate)
CREATE NONCLUSTERED INDEX [IDX_workorder_assetnum] ON dbo.workorder(assetnum)

如果assetnum表中的asset列不是主键,则另外:

CREATE NONCLUSTERED INDEX [IDX_asset_assetnum] ON dbo.asset(assetnum)

答案 1 :(得分:1)

您可以为相关子查询结果创建临时表,然后再加入。语法不正确,因为我没有你的表模式或数据,但想法是一样的。

CREATE TABLE #workTypes (worktype VARCHAR(X), assetnum VARCHAR(x))

INSERT INTO #workTypes
SELECT TOP 1 worktype, assetnum FROM dbo.workorder ORDER BY statusdate DESC

SELECT  a.isrunning,
        b.worktype, 
        a.status,
        *
FROM    dbo.asset a WITH (NOLOCK)
   INNER JOIN #worktypes b
      ON a.assetnum = b.assetnum
WHERE   a.assetnum IN ('list', 'of', 'asset', 'numbers')

答案 2 :(得分:0)

怎么样:

SELECT  a.isrunning,
        w.worktype,
        cnt = count(*)
FROM       dbo.asset a WITH (NOLOCK)
INNER JOIN dbo workorder w WITH (NOLOCK) on w.assetnum = a.assetnum
WHERE      a.assetnum IN ('list', 'of', 'asset', 'numbers')

这将为您提供每个资产的工作类型计数,并可能允许数据库服务器更有效地进行优化。还可以考虑添加索引或使用临时表,如其他答案所示。