编辑:我认为这是 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。它们是此服务器上唯一运行的东西。
我能做些什么 ?
谢谢