我编写了一个查询,该查询应该从一个表中获取所有行,并将子查询执行到第二个表,只从最近的记录中提取一个值。在 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 {
...
}
);
答案 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')
这将为您提供每个资产的工作类型计数,并可能允许数据库服务器更有效地进行优化。还可以考虑添加索引或使用临时表,如其他答案所示。