Проблемы производительности на ASP.NET MVC 2 с SQL Server - PullRequest
1 голос
/ 09 августа 2010

РЕДАКТИРОВАТЬ: Я думаю, что это проблема в подзапросе на запрос, сгенерированный LINQ, он получает все записи ... Но я не знаю, как я мог это исправить

Я сделал простое приложение ASP.NET MVC 2, которое выполняет SELECT-запросы к представлению, я получаю действительно низкую производительность, и хотя я делаю простой тест с jMeter (соединение 10 conccurents) при отключении кэша (я не хочу, чтобы все полагалось на не настраиваемый / экстремальный OutputCache)

Я вижу, что SQL Server перегружен, потребляя много ЦП (до 100%) и все его зарезервированное пространство памяти (512 МБ)

Вот код действия, который вызывает проблемы (ручные транзакции, потому что он вызывает DeadLock с другой программой, которая вставляет новые данные в базу данных):

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 без каких-либо проблем с производительностью. (Двухъядерный, 3 Гб оперативной памяти)

Выбор счетчика (*) в GlobalView возвращает ~ 270 000 строк, индексы перестраиваются ежедневно, и в объяснительной демонстрации используются все кластерные индексы.

Я получаю среднее время ответа HTTP 8000 мс, в SQL Server Management Studio среднее время ЦП для этого запроса SQL составляет 866 мс, а средний логический IO - 7 592,03.

Размер файла базы данных, если ~ 180MB

Я использую Windows Server 2008 R2 Enterprise Edition, ASP.NET MVC 2 с IIS 7.5 и SQL Server 2008 R2 Express Edition с расширенными службами. Они единственные, что работают на этом сервере.

Что я могу сделать?

Спасибо

Ответы [ 3 ]

1 голос
/ 09 августа 2010

Просто из любопытства: не добавит ли .ToList() в конец строки var messages = ... help?

1 голос
/ 09 августа 2010

Я думаю, вы получили запрос от SQL Server Profiler.Сохраните результат и передайте его в помощник по настройке ядра СУБД.Это может помочь вам создать дополнительные индексы и статистику.

0 голосов
/ 09 августа 2010

Я нашел проблему,

Я заменил «orderby globalView.MessagePostDate по убыванию» на «orderby globalView.MessageId по убыванию», потому что в MessagePostDate нет индекса, и это намного лучше!

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...