gpt4 book ai didi

nhibernate - 如何在 nhibernate 中使用 ToFuture?

转载 作者:行者123 更新时间:2023-12-02 02:21:01 25 4
gpt4 key购买 nike

假设我有这些问题

// Linq 
var allRecords = session.Query<Table1P>().FetchMany(x => x.Table2).FetchMany(x => x.Table3).FetchMany(x => x.Table4).FetchMany(x => x.Table6).ToList();

// Hql
string hqlQuery = @"from Table1 tbl1
left join fetch tbl1.Table2 tbl2
left join fetch tbl1.Table3
left join fetch tbl1.Table4
left join fetch tbl1.Table6
left join fetch tbl2.Table5s";

在上述情况下,我需要执行所有这些连接以停止延迟加载并进行预加载。现在这会在 nhibernate 分析器中产生关于连接过多的警报。

http://nhprof.com/Learn/Alerts/TooManyJoins

因此,停止此警报的一种方法是分解连接。并进行多次查询。这就是我想要做的。然而与此同时,我一直在阅读有关 future 功能的信息,我认为它可以让我分解查询(以停止过多的连接)但仍然一次执行它。

编辑

我一直在尝试 ToFuture 并发现它在尝试限制要返回的数据量时速度较慢(如果我尝试恢复所有内容则它会更快,因为它不会崩溃)。

  var allRecords = session.Query<Table1P>().FetchMany(x => x.Table2).FetchMany(x => x.Table3).FetchMany(x => x.Table4).FetchMany(x => x.Table6).Take(3000).ToList();

// result (2.731 seconds), row count 3000, duration 8 ms/ 2013 ms

select TOP (3000 /* @p0 */) table1p0_.Id as Id1_0_,
table2x1_.Id as Id2_1_,
table3x2_.Id as Id3_2_,
table4x3_.Id as Id4_3_,
table6x4_.Id as Id6_4_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table2x1_.F1 as F2_2_1_,
table2x1_.F2 as F3_2_1_,
table2x1_.F3 as F4_2_1_,
table2x1_.Table1_id as Table5_2_1_,
table2x1_.Table1_id as Table5_0__,
table2x1_.Id as Id0__,
table3x2_.F1 as F2_3_2_,
table3x2_.F2 as F3_3_2_,
table3x2_.F3 as F4_3_2_,
table3x2_.Table1_id as Table5_3_2_,
table3x2_.Table1_id as Table5_1__,
table3x2_.Id as Id1__,
table4x3_.F1 as F2_4_3_,
table4x3_.F2 as F3_4_3_,
table4x3_.F3 as F4_4_3_,
table4x3_.Table1_id as Table5_4_3_,
table4x3_.Table1_id as Table5_2__,
table4x3_.Id as Id2__,
table6x4_.F1 as F2_6_4_,
table6x4_.F2 as F3_6_4_,
table6x4_.F3 as F4_6_4_,
table6x4_.Table1_id as Table5_6_4_,
table6x4_.Table1_id as Table5_3__,
table6x4_.Id as Id3__
from Table1 table1p0_
left outer join [Table2] table2x1_
on table1p0_.Id = table2x1_.Table1_id
left outer join [Table3] table3x2_
on table1p0_.Id = table3x2_.Table1_id
left outer join [Table4] table4x3_
on table1p0_.Id = table4x3_.Table1_id
left outer join [Table6] table6x4_
on table1p0_.Id = table6x4_.Table1_id

使用 future

// result (4.808 seconds), row count 6944 / 75/ 374, duration 1ms / 4022 ms

// will load the Entities with Table2 fetched
var allRecords = session.Query<Table1P>()
.FetchMany(x => x.Table2)
.ToFuture()
.Take(3000);

// will load the Entities with Table3 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table3)
.ToFuture();

// will load the Entities with Table4 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table4)
.ToFuture();

// will load the Entities with Table6 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table6)
.ToFuture();

// will trigger all queries at once and the session cache will make sure,
// that the results of all queries fill the same Entities
allRecords.ToList();


select table1p0_.Id as Id1_0_,
table2x1_.Id as Id2_1_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table2x1_.F1 as F2_2_1_,
table2x1_.F2 as F3_2_1_,
table2x1_.F3 as F4_2_1_,
table2x1_.Table1_id as Table5_2_1_,
table2x1_.Table1_id as Table5_0__,
table2x1_.Id as Id0__
from Table1 table1p0_
left outer join [Table2] table2x1_
on table1p0_.Id = table2x1_.Table1_id;



select table1p0_.Id as Id1_0_,
table3x1_.Id as Id3_1_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table3x1_.F1 as F2_3_1_,
table3x1_.F2 as F3_3_1_,
table3x1_.F3 as F4_3_1_,
table3x1_.Table1_id as Table5_3_1_,
table3x1_.Table1_id as Table5_0__,
table3x1_.Id as Id0__
from Table1 table1p0_
left outer join [Table3] table3x1_
on table1p0_.Id = table3x1_.Table1_id;



select table1p0_.Id as Id1_0_,
table4x1_.Id as Id4_1_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table4x1_.F1 as F2_4_1_,
table4x1_.F2 as F3_4_1_,
table4x1_.F3 as F4_4_1_,
table4x1_.Table1_id as Table5_4_1_,
table4x1_.Table1_id as Table5_0__,
table4x1_.Id as Id0__
from Table1 table1p0_
left outer join [Table4] table4x1_
on table1p0_.Id = table4x1_.Table1_id;



select table1p0_.Id as Id1_0_,
table6x1_.Id as Id6_1_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table6x1_.F1 as F2_6_1_,
table6x1_.F2 as F3_6_1_,
table6x1_.F3 as F4_6_1_,
table6x1_.Table1_id as Table5_6_1_,
table6x1_.Table1_id as Table5_0__,
table6x1_.Id as Id0__
from Table1 table1p0_
left outer join [Table6] table6x1_
on table1p0_.Id = table6x1_.Table1_id;

从 nhibernate 分析器中获取的查询和时间。通过使用其中一组代码运行一次测试来运行测试,记录结果,停止 .net 开发服务器,然后运行另一组代码。

表 1 - 6200 行表 2 - 744 行表 3 - 75 行表 4 - 374 行表 6 - 300 行

几乎表 1 对所有其他表都是一对多的。

最佳答案

// will load the Entities with Table2 fetched
var allRecords = session.Query<Table1P>()
.FetchMany(x => x.Table2)
.ToFuture();

// will load the Entities with Table3 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table3)
.ToFuture();

// will load the Entities with Table4 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table4)
.ToFuture();

// will load the Entities with Table6 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table6)
.ToFuture();

// will trigger all queries at once and the session cache will make sure,
// that the results of all queries fill the same Entities
allRecords.ToList();

改变

       .ToFuture()
.Take(3000);

       .Take(3000);
.ToFuture()

更新:

// Hql
var allRecords = session.CreateQuery("from Table1 left join fetch tbl1.Table2")
.ToFuture<Table1>();

...

奇怪的是,这比 big join 慢。我现在不能在这里测试。也许数据库中没有那么多行,多个结果集的开销大于扩展连接的开销。你能尝试在 db 中使用更多数据吗?

关于nhibernate - 如何在 nhibernate 中使用 ToFuture?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8186239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com