1

编辑:我认为这是 LINQ 生成查询的子查询的问题,它获取所有记录......但我不知道如何解决它

我制作了一个简单的 ASP.NET MVC 2 应用程序,该应用程序在视图上执行 SELECT 查询,但性能非常差,并且在使用 jMeter(10 个并发连接)进行简单基准测试时禁用缓存(我不希望一切都依赖于不可定制/极端的OutputCache)

我看到 SQL Server 过载,消耗大量 CPU(高达 100%)及其所有保留的内存空间(512MB)

这是导致问题的操作代码(手动事务,因为它会导致与在数据库中插入新数据的其他程序发生死锁):

public ActionResult Index(int page = 0)
{
    IronViperEntities db = new IronViperEntities();
    db.Connection.Open();
    DbTransaction transaction = db.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
    var messages = (from globalView in db.GlobalViews orderby globalView.MessagePostDate descending select globalView).Skip(page*perPage).Take(perPage);
    transaction.Commit();
    db.Connection.Close();
    ViewData["page"] = page;
    ViewData["messages"] = messages;
    return View();
}

这是在数据库上执行的查询:

SELECT TOP (100) 
[Extent1].[MessageId] AS [MessageId], 
[Extent1].[MessageUuid] AS [MessageUuid], 
[Extent1].[MessageData] AS [MessageData], 
[Extent1].[MessagePostDate] AS [MessagePostDate], 
[Extent1].[ChannelName] AS [ChannelName], 
[Extent1].[UserName] AS [UserName], 
[Extent1].[UserUuid] AS [UserUuid], 
[Extent1].[ChannelUuid] AS [ChannelUuid]
FROM ( SELECT [Extent1].[MessageId] AS [MessageId], [Extent1].[MessageUuid] AS [MessageUuid], [Extent1].[MessageData] AS [MessageData], [Extent1].[MessagePostDate] AS [MessagePostDate], [Extent1].[ChannelName] AS [ChannelName], [Extent1].[UserName] AS [UserName], [Extent1].[UserUuid] AS [UserUuid], [Extent1].[ChannelUuid] AS [ChannelUuid], row_number() OVER (ORDER BY [Extent1].[MessagePostDate] DESC) AS [row_number]
    FROM (SELECT 
      [GlobalView].[MessageId] AS [MessageId], 
      [GlobalView].[MessageUuid] AS [MessageUuid], 
      [GlobalView].[MessageData] AS [MessageData], 
      [GlobalView].[MessagePostDate] AS [MessagePostDate], 
      [GlobalView].[ChannelName] AS [ChannelName], 
      [GlobalView].[UserName] AS [UserName], 
      [GlobalView].[UserUuid] AS [UserUuid], 
      [GlobalView].[ChannelUuid] AS [ChannelUuid]
      FROM [dbo].[GlobalView] AS [GlobalView]) AS [Extent1]
)  AS [Extent1]
WHERE [Extent1].[row_number] > 0
ORDER BY [Extent1].[MessagePostDate] DESC

查看代码:

SELECT     dbo.Messages.Id AS MessageId, dbo.Messages.Uuid AS MessageUuid, dbo.Messages.Data AS MessageData, dbo.Messages.PostDate AS MessagePostDate, 
                      dbo.Channels.Name AS ChannelName, dbo.Users.Name AS UserName, dbo.Users.Uuid AS UserUuid, dbo.Channels.Uuid AS ChannelUuid
FROM         dbo.Messages INNER JOIN
                      dbo.Users ON dbo.Messages.UserId = dbo.Users.Id INNER JOIN
                      dbo.Channels ON dbo.Messages.ChannelId = dbo.Channels.Id

我不认为服务器硬件有问题,我可以运行等效的 Rails/Grails 应用程序而不会出现任何性能问题。(双核,3Gb RAM)

GlobalView 上的 select count(*) 返回约 270.000 行,索引每天重建,并且解释显示它使用所有聚集索引。

我得到的 HTTP 平均响应时间为 8000 毫秒,SQL Server Management Studio 显示此 SQL 查询的平均 CPU 时间为 866 毫秒,平均逻辑 IO 为 7,592.03。

数据库文件大小,如果 ~180MB

我正在使用 Windows Server 2008 R2 Enterprise Edition、带有 IIS 7.5 的 ASP.NET MVC 2 和带有高级服务的 SQL Server 2008 R2 Express Edition。它们是此服务器上唯一运行的东西。

我能做些什么 ?

谢谢

4

3 回答 3

1

我猜你从 SQL Server Profiler 得到了查询。保存结果,并将其传递给数据库引擎优化顾问。这可能会帮助您创建额外的索引和统计信息。

于 2010-08-08T22:15:12.290 回答
1

只是出于好奇:在行.ToList()尾附加 a 不会有var messages = ...帮助吗?

于 2010-08-08T22:20:41.890 回答
0

我发现了问题,

我将“orderby globalView.MessagePostDate descending”替换为“orderby globalView.MessageId descending”,因为MessagePostDate 上没有任何索引,这样更好!

谢谢

于 2010-08-08T22:53:50.653 回答