我寫了一個lambda表達式,它產生了預期的結果,但它生成了一個絕對巨大的sql查詢,並且性能不佳。查看io /時間統計的底部。從lambda表達式生成sql server查詢的替代方法
是否有另一種方法來實現下面的查詢?
select distinct(searchterms) as SearchTerms, max(totalresults) FROM cmsSearchLog
where totalresults != 0 and searchterms like 'de%' group by searchterms
order by max(totalresults) desc
C#代碼片段:
// current lamda expression; has bad performance compared to above query
List<SearchTerm> existingSearchTerms1 = context.cmsSearchLogs.Where(oq =>
context.cmsSearchLogs.Where(q =>
q.SearchTerms.ToLower().Contains(terms.ToLower()) && q.TotalResults != 0)
.Select(s => s.SearchTerms)
.Distinct()
.Contains(oq.SearchTerms))
.Select(a => new { a.SearchTerms, a.TotalResults })
.GroupBy(gb => gb.SearchTerms)
.OrderByDescending(ob => ob.Max(m => m.TotalResults))
.Select(s => new SearchTerm()
{
SearchTerms = s.FirstOrDefault().SearchTerms,
TotalResults = s.FirstOrDefault().TotalResults
}
)
.ToList();
// get the suggestions back as a list of strings
List<string> suggestions = Enumerable.Range(0,
existingSearchTerms1.Count())
.Select(x => existingSearchTerms1.ElementAt(x).SearchTerms).ToList();
這是民營類從查詢
private class SearchTerm
{
public string SearchTerms { get; set; }
public int TotalResults { get; set; }
}
保存結果
由lambda表達式生成的SQL是巨大的:
SELECT
[Project13].[C2] AS [C1],
[Project13].[C3] AS [C2],
[Project13].[C4] AS [C3]
FROM (SELECT
[Project12].[C1] AS [C1],
1 AS [C2],
[Project12].[C2] AS [C3],
[Project12].[C3] AS [C4]
FROM (SELECT
[Project8].[C1] AS [C1],
[Project8].[C2] AS [C2],
(SELECT TOP (1)
[Extent5].[TotalResults] AS [TotalResults]
FROM [dbo].[cmsSearchLog] AS [Extent5]
WHERE (EXISTS (SELECT 1 AS [C1]
FROM (SELECT DISTINCT
[Extent6].[SearchTerms] AS [SearchTerms]
FROM [dbo].[cmsSearchLog] AS [Extent6]
WHERE ((CAST(CHARINDEX(LOWER('dew'),
LOWER([Extent6].[SearchTerms])) AS int)) > 0)
AND (0 <> [Extent6].[TotalResults])
) AS [Distinct3]
WHERE [Distinct3].[SearchTerms] = [Extent5].[SearchTerms]
)) AND ([Project8].[SearchTerms] = [Extent5].[SearchTerms]))
AS [C3]
FROM (SELECT
[Project7].[C1] AS [C1],
[Project7].[SearchTerms] AS [SearchTerms],
[Project7].[C2] AS [C2]
FROM (SELECT
[Project3].[C1] AS [C1],
[Project3].[SearchTerms] AS [SearchTerms],
(SELECT TOP (1)
[Extent3].[SearchTerms] AS [SearchTerms]
FROM [dbo].[cmsSearchLog] AS [Extent3]
WHERE (EXISTS (SELECT 1 AS [C1] FROM (SELECT DISTINCT
[Extent4].[SearchTerms] AS [SearchTerms]
FROM [dbo].[cmsSearchLog] AS [Extent4]
WHERE ((CAST(CHARINDEX(LOWER('dew'),
LOWER([Extent4].[SearchTerms])) AS int)) > 0)
AND (0 <> [Extent4].[TotalResults])) AS [Distinct2]
WHERE [Distinct2].[SearchTerms] = [Extent3].[SearchTerms]
)) AND ([Project3].[SearchTerms] = [Extent3].[SearchTerms])) AS [C2]
FROM (SELECT
[GroupBy1].[A1] AS [C1],
[GroupBy1].[K1] AS [SearchTerms]
FROM (SELECT
[Extent1].[SearchTerms] AS [K1],
MAX([Extent1].[TotalResults]) AS [A1]
FROM [dbo].[cmsSearchLog] AS [Extent1]
WHERE EXISTS (SELECT 1 AS [C1]
FROM (SELECT DISTINCT [Extent2].[SearchTerms]
AS [SearchTerms] FROM [dbo].[cmsSearchLog] AS [Extent2]
WHERE ((CAST(CHARINDEX(LOWER('dew'),
LOWER([Extent2].[SearchTerms])) AS int)) > 0)
AND (0 <> [Extent2].[TotalResults])) AS [Distinct1]
WHERE [Distinct1].[SearchTerms] = [Extent1].[SearchTerms])
GROUP BY [Extent1].[SearchTerms]) AS [GroupBy1]
) AS [Project3]
) AS [Project7]
) AS [Project8]
) AS [Project12]
) AS [Project13]
ORDER BY [Project13].[C1] ASC
I執行兩個查詢與io和時間統計打開,結果如下。 (注意:lambda生成的查詢是第一個,我的手寫查詢第二)因此,這證實了我懷疑生成的查詢執行可怕比我實際需要查詢。
(8 row(s) affected)
Table 'cmsSearchLog'. Scan count 6, logical reads 106, physical reads 0,
read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 1 ms.
(7 row(s) affected)
Table 'cmsSearchLog'. Scan count 1, logical reads 5, physical reads 0,
read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
從來沒有人聲稱linq to sql每次都會生成完美的sql。這看起來像使用手工優化的存儲過程而不是lambda生成的調用的好地方。 – asawyer