Как можно оптимизировать производительность настольного приложения EF Code First с таблицами, предназначенными в основном только для чтения? - PullRequest
1 голос
/ 22 декабря 2011

Факты:

  • У меня есть настольное приложение, поддерживаемое базой данных SQL CE.
  • Многие таблицы доступны только для чтения.
  • Я использую EF Code First для генерации базы данных и обработки грубых операций.
  • Я обычно оставляю один DbContext открытым для всего сеанса и располагаю при выходе из приложения. (Примечание: я пытался создавать новый DbContext чаще и обнаружил, что производительность на самом деле была хуже. Кроме того, мне никогда не нужно откатывать изменения.)
  • Для некоторых из моих сущностей я добавил несколько геттеров для предоставления необходимых данных, полученных из других свойств сущности. Некоторые из этих геттеров фактически выполняют запросы LINQ (что, я подозреваю, является частью моей проблемы).

Все работает, но теперь я понимаю, что мне нужно провести некоторую оптимизацию. Производительность в целом несколько вялая, но меня особенно беспокоит один действительно гигантский запрос, который пользователи должны периодически запускать, который сводит практически всю базу данных в одну таблицу, а затем выводит ее в текстовый файл с разделителями. Этот запрос занимает гораздо больше времени, чем хотелось бы.

Одна идея, которую я имею для ускорения, состоит в том, чтобы хранить все, что доступно только для чтения, в List вместо того, чтобы извлекать это из моего DbContext каждый раз, когда мне это нужно. Сложность в том, что, хотя я мог бы легко получить все свои Car сущности из DbContext и сохранить их в списке, как бы я гарантировал, что все «вспомогательные свойства», такие как public virtual ICollection<Wheel> Wheels { get; set; } или public virtual Engine Engine { get; set; }, будут сохранены также? Бесполезно выполнять итерацию по всем Car сущностям, если все связанные сущности также не повторяются.

Другая идея, которая у меня есть для повышения производительности, заключается в том, чтобы предложить способ кэширования геттеров, которые наиболее интенсивно используют процессор. Как я упоминал выше, некоторые из моих геттеров фактически выполняют запросы LINQ. Я знаю, что это снижает производительность, но поскольку некоторые из них зависят от данных, которые могут измениться, кэширование становится довольно сложным. У меня такое чувство, что потребуется реализация INotifyPropertyChanged.

То, что я хотел бы, - это стратегия повышения производительности без отбрасывания всего хорошего, что EF уже делает для меня. Нет смысла сохранять что-либо в списке, например, если EF уже итерировал список и не будет повторять список снова, пока он не устареет.

Учитывая мою конкретную ситуацию и описанную выше историю, какую стратегию (ы) вы порекомендуете ускорить мое приложение?

Разъяснение

Как я уже писал в комментариях ниже ...

Для большого запроса я перебираю все свои сущности (помещая каждую в List<TEntity>), затем выполняю гигантское объединение, затем выбираю нужные мне данные. Для этого окончательного выбора некоторые данные являются необработанными (базовое свойство объекта), а некоторые рассчитываются (получатель свойства, который зависит от базовых свойств объекта). Для вычисляемых свойств иногда используются запросы LINQ. Таким образом, большая часть тяжелой работы выполняется в C #, а не через базу данных (которая основана на файлах и представляет собой SQL CE).

Для всего остального в моем приложении. Я напрямую запрашиваю базу данных, когда это возможно, и не пытаюсь что-либо кэшировать. Если бы я мог найти способ полностью кэшировать все, что доступно только для чтения, в память, я должен был бы поверить, что это улучшило бы производительность, но я не совсем понимаю, как это сделать, учитывая, что (1) у меня есть объекты, которые хранят другие сущности и (2) сущности имеют геттеры, некоторые из которых выполняют запросы.

Ответы [ 2 ]

2 голосов
/ 22 декабря 2011

Кэширование - твой друг: http://support.microsoft.com/kb/323290

0 голосов
/ 22 декабря 2011

Я предложу настройку производительности на уровне базы данных; создание соответствующих индексов, если это применимо. Мне никогда не приходилось настраивать базу данных SQLCE, поэтому быстрый поиск в Google дал http://www.sql -server-performance.com / 2003 / sql-server-ce / и http://msdn.microsoft.com/en-us/library/ms172984(v=sql.90).aspx.

Для запроса соединения (представление вашего отчета) вы можете ввести материализованные представления (если таковые существуют в ce).

...