【发布时间】:2012-02-06 12:36:00
【问题描述】:
如果您查看我们的街机主页:
右上角有一个框,显示最后玩此游戏的人。在我使用的分析器中,它显示这需要 900 毫秒才能运行,这大约是总页面加载时间的 80%。
查询比较简单:
// Recent players
using (MainContext db = new MainContext())
{
var q = (from c in db.tblArcadeGamePlays
join a in db.tblProfiles on c.UserID equals a.UserID
where c.UserID != 0
select new
{
c.UserID,
c.tblForumAuthor.Username,
a.EmailAddress,
Date = (from d in db.tblArcadeGamePlays where d.UserID == c.UserID orderby d.Date descending select new { d.Date }).Take(1).Single().Date
})
.Distinct()
.OrderByDescending(c => c.Date)
.Take(16);
但它对我的需求来说太慢了。
在此设置输出缓存不合适,因为此框最好是实时的。此外,在正常页面加载之上的 900 毫秒对于一个用户来说也太慢了,因此希望尽可能避免这种情况。
有人对我如何加快速度有任何想法吗?我目前的两个想法是:
- 一个新的数据库表,其中包含最后的玩家,无需加入
- 存储在某处的字段保存该框的 HTML,每次发生的新游戏都会重建该字段
- 两者的结合
两者都很丑!任何帮助表示赞赏。
根据要求,linqpad 结果
Lambda
TblArcadeGamePlays
.Join (
TblProfiles,
c => c.UserID,
a => a.UserID,
(c, a) =>
new
{
c = c,
a = a
}
)
.Where (temp0 => (temp0.c.UserID != 0))
.Select (
temp0 =>
new
{
UserID = temp0.c.UserID,
Username = temp0.c.User.Username,
EmailAddress = temp0.a.EmailAddress,
Date = TblArcadeGamePlays
.Where (d => (d.UserID == temp0.c.UserID))
.OrderByDescending (d => d.Date)
.Select (
d =>
new
{
Date = d.Date
}
)
.Take (1)
.Single ().Date
}
)
.Distinct ()
.OrderByDescending (c => c.Date)
.Take (16)
SQL
-- Region Parameters
DECLARE @p0 Int = 0
-- EndRegion
SELECT TOP (16) [t6].[UserID], [t6].[Username], [t6].[EmailAddress], [t6].[value] AS [Date2]
FROM (
SELECT DISTINCT [t5].[UserID], [t5].[Username], [t5].[EmailAddress], [t5].[value]
FROM (
SELECT [t0].[UserID], [t2].[Username], [t1].[EmailAddress], (
SELECT [t4].[Date]
FROM (
SELECT TOP (1) [t3].[Date]
FROM [tblArcadeGamePlays] AS [t3]
WHERE [t3].[UserID] = [t0].[UserID]
ORDER BY [t3].[Date] DESC
) AS [t4]
) AS [value]
FROM [tblArcadeGamePlays] AS [t0]
INNER JOIN [tblProfile] AS [t1] ON [t0].[UserID] = [t1].[UserID]
INNER JOIN [tblForumAuthor] AS [t2] ON [t2].[Author_ID] = [t0].[UserID]
) AS [t5]
WHERE [t5].[UserID] <> @p0
) AS [t6]
ORDER BY [t6].[value] DESC
查询计划
【问题讨论】:
-
尝试使用 group by 而不是 distinct。
-
我假设这是 LINQ to SQL 或实体框架?
-
您还可以使用 SQL Profiler 来准确找出正在生成的查询以及需要多长时间。如果您从未使用过 SQL Profiler,这里是一个非常好的tutorial by Brent Ozar
-
@Carlos 谢谢,虽然我没有这个版本的分析器,但我可能会购买开发版进行开发,因为我认为它包含它并且现在可能对我有用
-
对于您试图从数据库中获取的信息,这似乎是一个非常复杂的查询。可能值得尝试用 SQL 编写它并从它向后工作到 LINQ?
标签: c# asp.net performance linq optimization