Я хотел повысить производительность своего приложения, устранив проблему N + 1.Это не проблема для мест, где используется API QueryOver / Criteria, но я обнаружил некоторые проблемы с оптимизацией запросов NativeSQL.Проблема в том, что даже когда я говорю NHibernate присоединить все связанные объекты в одном запросе, он выполняет ленивую загрузку для всех элементов коллекции.Интересно, почему это так.
private IQuery GetRandomPaidIndustrialPropertyQuery(int maxItems)
{
var sql =
" SELECT {ip.*}, {ph.*}, {lp.*} " +
" FROM industrial_property ip " +
" JOIN object o ON ip.object_id = o.id " +
" JOIN photo p on p.object_id = o.id " +
" LEFT JOIN production_hall ph on (ip.id = ph.industrial_property_id) " +
" LEFT JOIN land_plot lp on (ip.id = lp.industrial_property_id) " +
" WHERE o.active = TRUE AND o.visible = TRUE AND o.removed = FALSE AND
o.draft = FALSE " +
" ORDER BY RANDOM() ASC " +
" LIMIT :maxItems ";
var result = CurrentSession.CreateSQLQuery(sql)
.AddEntity("ip", typeof(IndustrialPropertyEntity))
.AddJoin("ph", "ip.ProductionHall")
.AddJoin("lp", "ip.LandPlot")
.SetInt32("maxItems", maxItems);
var test = result.List(); // this is the place where i put a breakpoint to see the result of NH Profiler
return result;
}
public class IndustrialPropertyEntity : Entity
{
...
public virtual ProductionHallEntity ProductionHall { get; set; }
public virtual LandPlotEntity LandPlot { get; set; }
...
}
public class IndustrialPropertyEntityMap : ClassMap<IndustrialPropertyEntity>
{
public IndustrialPropertyEntityMap()
{
...
HasOne(x => x.ProductionHall).Cascade.All().PropertyRef("IndustrialProperty").LazyLoad();
HasOne(x => x.LandPlot).Cascade.All().PropertyRef("IndustrialProperty").LazyLoad();
...
}
}
Как вы можете видеть на картинке выше, в этом фрагменте N + 1.
Я ожидаю, что NHibernate не будет выполнять ленивую загрузку связанных объектов ProductionHall, LandPlot в этом запросе.