Производительность NHibernate Paging (лучший вариант) - PullRequest
0 голосов
/ 09 ноября 2010

В этом простом случае:

public class Person
{
     public int Id {get;set;}
     public int Name {get;set;}
}
  • Мне нужно сгенерировать грид с разбивкой по страницам и упорядочением
  • В моей базе данных около 100 тысяч человек

Какая опция имеет лучшую производительность:

1) Получить все элементы в первый раз и после использования кэш-памяти первого уровня NHibernate, пример:

personRep.FindAll().OrderBy(s =>s.Name).AsPagination(pageNumber,pageSize);

Obs .: AsPagination - это метод расширения ...

2) Получить только актуальную страницу из базы данных, например:

   public virtual IList<T> GetPaginedList(int __pageIndex, int __pageSize,out int __total)
    {            
        var _rowCount = Session.CreateCriteria(typeof(T))
            .SetProjection(Projections.RowCount()).FutureValue<Int32>();

        var _results = Session.CreateCriteria(typeof(T))
            .SetFirstResult(__pageIndex * __pageSize)
            .SetMaxResults(__pageSize)
            .Future<T>();

        __total = _rowCount.Value; 
        return _results;
    } 

Ответы [ 2 ]

4 голосов
/ 09 ноября 2010

Второй вариант будет наиболее подходящим.

Бесполезно извлекать все экземпляры за один раз, когда вы (пользователь), возможно, даже не «используете» все эти экземпляры.

Если класс Person является «тяжелым» классом с большим количеством ассоциаций, было бы еще лучше создать класс PersonView, который содержит только те свойства, которые вы хотите отобразить в Grid.

Вам не нужно отображать этот PersonView класс, вам просто нужно «импортировать» его, чтобы NHibernate знал о его существовании.Затем вы создаете запрос к классу Person и определяете, что AliasToBean Transformer должен использоваться для преобразования экземпляров Person в экземпляры PersonView.

Таким образом, NHibernate сможетсгенерировать запрос, который извлекает только необходимые столбцы из БД и заполнит его PersonView экземплярами.

1 голос
/ 09 ноября 2010

Как и многие другие вопросы производительности поиска данных, какие из них лучше, будет зависеть от сценария использования.

Вариант 1 лучше, если пользователь, вероятно, будет просматривать большинство или все страницы до того, как данные станут слишком устаревшими, чтобы быть полезными. Это также лучше в случаях относительно небольших общих наборов результатов (2-3 страницы) и в тех случаях, когда набор результатов не сильно изменится (т. Е. Извлекает пользовательские разрешения из БД), что позволяет долго хранить весь набор данных в памяти - повышение производительности будущих запусков за счет исключения кругового обхода сети.

Вариант 2 лучше подходит для ситуаций, связанных с длинными страницами данных и / или общими результирующими наборами, «широкими» записями или данными, которые изменяются достаточно часто, чтобы локальное кеширование не принесло больших результатов. Он распределяет стоимость извлечения записей по всему набору результатов в той степени, которая необходима для их отображения. Такая «ленивая загрузка» результатов разбивки на страницы увеличивает общее время и издержки на получение записей (поскольку существует больше циклов), но ваши пользователи с гораздо большей вероятностью заметят и пожалуются о десятисекундном времени обработки их результатов поиска. чем полсекунды на страницу.

...