2012-06-19 3 views
1

У меня есть сайт ASP.NET MVC2, подключающийся к базе данных MySQL через DbLinq. Существует определенный набор действий, которые выполняются через определенные промежутки времени на сайте, который включает в себя цикл по определенному набору записей в нескольких таблицах и их обновление и добавление некоторых новых записей в некоторые другие таблицы.Можно ли улучшить производительность отслеживания объектов DbLinq?

Я тестировал данные с умеренным размером. В моем конкретном тестовом наборе прямо сейчас, при обновлении он заканчивает вставку 44 новых строк и обновление 81 других строк. Но мой призыв к SubmitChanges() заканчивается очень долгое время - ~ 3-4 минуты, что кажется долгое время (то, что я думал) относительно небольшим числом изменений в БД.

В конце концов я сделал несколько простых профилей, и я обнаружил, что проблема не связана с выполнением запроса в базе данных или даже с построением запроса. Большинство времени, похоже, занято вызовом внутри UpdateEntity в AllTrackedEntities.ContainsReference().

Чтобы дать некоторые реальные цифры, из недавнего теста я имел:

  • Время в SubmitChangesImpl: 204884 мс
    • Время в UpdateEntity: 200908 мс
      • Время в ContainsReference: 148173 мс
      • Время в QueryBuilder.GetUpdateQuery: 685 ms
      • Время в QueryRunner.Update: 28 мс
      • Время в UpdateReferencedObjects: 49958 мс

Как вы можете видеть, построение и запуск запроса SQL является ничтожной по сравнению с количеством времени, затраченного проверять, если существует ссылка на сущности мы обновляемся (если нет ссылки, объект вставлен, хотя в этом случае все обновленные сущности существуют). Хотя я понимаю, почему это происходит, чтобы сохранить целостность данных и т. Д., Это убивает производительность этих регулярных операций обновления.

Я посмотрел на установку ObjectTrackingEnabled на false, но это делает DataContext доступным только для чтения, и это бесполезно для меня - моя проблема связана с производительностью обновлений.

Есть ли что-то, что можно сделать для повышения эффективности обновлений? Я использую DbLinq менее оптимальным способом с точки зрения попыток пропустить 40-50 вставок и 80+ обновлений в одном представлении? Если это так, есть ли лучший способ сделать это?

+0

Ваша логика должна мешать, показать какой-то код - или хотя бы дать краткий пример, который воспроизводит проблему, которую вы имеете. Я строю сложные формы ввода, которые в конечном итоге отправляют около 18 записей для добавления в базу данных mysql с использованием EF 4.1, и это займет примерно 5-10 секунд, если это произойдет. –

+0

Используете ли вы один и тот же файл данных в течение длительного периода времени, то есть читаете некоторые строки, обновляете/добавляете некоторые строки, отправляете изменения, а затем повторяете с тем же dataContext? – hatchet

+0

@hatchet - Я знаю, что это было направлено на OP, но в моем репозитории я сохраняю изменения каждый раз при внесении изменений и все время использую один и тот же dataContext. Если он открывает и закрывает соединение, это может быть связано с временем. Однако мне кажется, что существует какая-то операция 'n!'. –

ответ

1

Если вы используете долгоживущие DataContexts, где вы читаете данные, изменяете данные, отправляете изменения, а затем повторяете с использованием одного и того же объекта DataContext, это может отрицательно сказаться на производительности. После того, как DataContext материализует сущность, он хранит ее внутренне для жизни DataContext как часть отслеживания объекта. Со временем этот внутренний кеш может стать большим, в некоторых случаях эффективно превращаясь в кеш памяти в большой части вашей базы данных. Это может замедлить работу и вызвать работу DataContext во время SubmitChanges.

DataContext должен быть недолговечным. Это срок службы должен быть единицей работы. Создайте его, используйте его для чего-то, а затем утилизируйте.

Вот еще некоторые детали:

Why would reusing a DataContext have a negative performance impact?

и это кто-то близко к продукту:

http://blogs.msdn.com/b/dinesh.kulkarni/archive/2008/04/27/lifetime-of-a-linq-to-sql-datacontext.aspx

Долговечное использование: DataContext не сам перезаписать объекты после того, как вы получите их через запросы. По прошествии времени возвращаемые объекты могут быть устаревшими, если они часто меняются.

Life after SubmitChanges(): DataContext может использоваться после SubmitChanges(), но нужно быть осторожным. SubmitChanges() делает все трудную работу по выяснению всех изменений, внесенных вами в графический объект . Он заказывает операции CUD и предоставляет оптимистичную проверку параллельности при детализации каждого измененного объекта .

Смежные вопросы