如果在请求期间由hibernate(V3.5.1)执行SQL语句,我目前会出现大量性能问题。所以我试着深入了解细节,以了解渴望获取的细节。
基本上问题似乎源于我们使用引用两个匹配的配置文件实体的匹配实体的问题。看起来hibernate只是通过连接来获取配置文件,但不是两者兼而有之。另一个是由select加载的。
[MatchingData] ---- searchingProfile--> [ProfileData] ---- searchData --> [SearchData]
|
+- potentialMatch ---> [ProfileData] ---- searchData --> [SearchData]
所有关联都标记为FetchMode.Join和@ManyToOne(@OneToOne(可选= false,fetch = FetchType.EAGER,cascade = ...)
我已经设置了一个简单的例子,用HQL和Criterieas测试各种方法来通过hibernate获取MatchingData。不幸的是,锅炉板代码太大了,不能详细地发布给她。我可以按需提供。
测试
System.out.println("-------------------- this should be a single SQL statement ? ------------------------");
List<MatchingData> result1 = hibernateTemplate.find(
"from MatchingData");
openSession.clear();
System.out.println("-------------------- this should be a single SQL statement ? ------------------------");
List<MatchingData> result2 = hibernateTemplate.find(
"from MatchingData where potentialMatch.firstName!=null");
openSession.clear();
System.out.println("-------------------- this should be a single SQL statement ? ------------------------");
Criteria matchingDataCriteria1 = openSession.createCriteria(MatchingData.class);
matchingDataCriteria1.createCriteria("potentialMatch").add(Restrictions.eq("firstName", FIRSTNAME_TEST_PM));
matchingDataCriteria1.list();
openSession.clear();
System.out.println("-------------------- this is a a single SQL statement ? ------------------------");
Criteria matchingDataCriteria2 = openSession.createCriteria(MatchingData.class);
matchingDataCriteria2.list();
openSession.clear();
在数据库中有2个MatchingData和3个涉及ProfileData的结果是
-------------------- this should be a single SQL statement ? ------------------------
Hibernate: select matchingda0_.id as id3_, matchingda0_.potentialMatch as potentia2_3_, matchingda0_.searchingProfile as searchin3_3_ from MatchingData matchingda0_
Hibernate: select profiledat0_.id as id0_3_, profiledat0_.firstName as firstName0_3_, profiledat0_.kontaktSparkasse_BLZ as kontaktS5_0_3_, profiledat0_.lastName as lastName0_3_, profiledat0_.profileType as profileT4_0_3_, profiledat0_.searchData_id as searchData6_0_3_, institutsd1_.BLZ as BLZ2_0_, institutsd1_.name as name2_0_, institutsd1_.parentHub_BLZ as parentHub3_2_0_, institutsd2_.BLZ as BLZ2_1_, institutsd2_.name as name2_1_, institutsd2_.parentHub_BLZ as parentHub3_2_1_, searchdata3_.id as id1_2_, searchdata3_.fakeContent as fakeCont2_1_2_ from ProfileData profiledat0_ inner join InstitutsData institutsd1_ on profiledat0_.kontaktSparkasse_BLZ=institutsd1_.BLZ left outer join InstitutsData institutsd2_ on institutsd1_.parentHub_BLZ=institutsd2_.BLZ left outer join SearchData searchdata3_ on profiledat0_.searchData_id=searchdata3_.id where profiledat0_.id=?
Hibernate: select profiledat0_.id as id0_3_, profiledat0_.firstName as firstName0_3_, profiledat0_.kontaktSparkasse_BLZ as kontaktS5_0_3_, profiledat0_.lastName as lastName0_3_, profiledat0_.profileType as profileT4_0_3_, profiledat0_.searchData_id as searchData6_0_3_, institutsd1_.BLZ as BLZ2_0_, institutsd1_.name as name2_0_, institutsd1_.parentHub_BLZ as parentHub3_2_0_, institutsd2_.BLZ as BLZ2_1_, institutsd2_.name as name2_1_, institutsd2_.parentHub_BLZ as parentHub3_2_1_, searchdata3_.id as id1_2_, searchdata3_.fakeContent as fakeCont2_1_2_ from ProfileData profiledat0_ inner join InstitutsData institutsd1_ on profiledat0_.kontaktSparkasse_BLZ=institutsd1_.BLZ left outer join InstitutsData institutsd2_ on institutsd1_.parentHub_BLZ=institutsd2_.BLZ left outer join SearchData searchdata3_ on profiledat0_.searchData_id=searchdata3_.id where profiledat0_.id=?
Hibernate: select profiledat0_.id as id0_3_, profiledat0_.firstName as firstName0_3_, profiledat0_.kontaktSparkasse_BLZ as kontaktS5_0_3_, profiledat0_.lastName as lastName0_3_, profiledat0_.profileType as profileT4_0_3_, profiledat0_.searchData_id as searchData6_0_3_, institutsd1_.BLZ as BLZ2_0_, institutsd1_.name as name2_0_, institutsd1_.parentHub_BLZ as parentHub3_2_0_, institutsd2_.BLZ as BLZ2_1_, institutsd2_.name as name2_1_, institutsd2_.parentHub_BLZ as parentHub3_2_1_, searchdata3_.id as id1_2_, searchdata3_.fakeContent as fakeCont2_1_2_ from ProfileData profiledat0_ inner join InstitutsData institutsd1_ on profiledat0_.kontaktSparkasse_BLZ=institutsd1_.BLZ left outer join InstitutsData institutsd2_ on institutsd1_.parentHub_BLZ=institutsd2_.BLZ left outer join SearchData searchdata3_ on profiledat0_.searchData_id=searchdata3_.id where profiledat0_.id=?
-------------------- this should be a single SQL statement ? ------------------------
Hibernate: select matchingda0_.id as id3_, matchingda0_.potentialMatch as potentia2_3_, matchingda0_.searchingProfile as searchin3_3_ from MatchingData matchingda0_ cross join ProfileData profiledat1_ where matchingda0_.potentialMatch=profiledat1_.id and (profiledat1_.firstName is not null)
Hibernate: select profiledat0_.id as id0_3_, profiledat0_.firstName as firstName0_3_, profiledat0_.kontaktSparkasse_BLZ as kontaktS5_0_3_, profiledat0_.lastName as lastName0_3_, profiledat0_.profileType as profileT4_0_3_, profiledat0_.searchData_id as searchData6_0_3_, institutsd1_.BLZ as BLZ2_0_, institutsd1_.name as name2_0_, institutsd1_.parentHub_BLZ as parentHub3_2_0_, institutsd2_.BLZ as BLZ2_1_, institutsd2_.name as name2_1_, institutsd2_.parentHub_BLZ as parentHub3_2_1_, searchdata3_.id as id1_2_, searchdata3_.fakeContent as fakeCont2_1_2_ from ProfileData profiledat0_ inner join InstitutsData institutsd1_ on profiledat0_.kontaktSparkasse_BLZ=institutsd1_.BLZ left outer join InstitutsData institutsd2_ on institutsd1_.parentHub_BLZ=institutsd2_.BLZ left outer join SearchData searchdata3_ on profiledat0_.searchData_id=searchdata3_.id where profiledat0_.id=?
Hibernate: select profiledat0_.id as id0_3_, profiledat0_.firstName as firstName0_3_, profiledat0_.kontaktSparkasse_BLZ as kontaktS5_0_3_, profiledat0_.lastName as lastName0_3_, profiledat0_.profileType as profileT4_0_3_, profiledat0_.searchData_id as searchData6_0_3_, institutsd1_.BLZ as BLZ2_0_, institutsd1_.name as name2_0_, institutsd1_.parentHub_BLZ as parentHub3_2_0_, institutsd2_.BLZ as BLZ2_1_, institutsd2_.name as name2_1_, institutsd2_.parentHub_BLZ as parentHub3_2_1_, searchdata3_.id as id1_2_, searchdata3_.fakeContent as fakeCont2_1_2_ from ProfileData profiledat0_ inner join InstitutsData institutsd1_ on profiledat0_.kontaktSparkasse_BLZ=institutsd1_.BLZ left outer join InstitutsData institutsd2_ on institutsd1_.parentHub_BLZ=institutsd2_.BLZ left outer join SearchData searchdata3_ on profiledat0_.searchData_id=searchdata3_.id where profiledat0_.id=?
Hibernate: select profiledat0_.id as id0_3_, profiledat0_.firstName as firstName0_3_, profiledat0_.kontaktSparkasse_BLZ as kontaktS5_0_3_, profiledat0_.lastName as lastName0_3_, profiledat0_.profileType as profileT4_0_3_, profiledat0_.searchData_id as searchData6_0_3_, institutsd1_.BLZ as BLZ2_0_, institutsd1_.name as name2_0_, institutsd1_.parentHub_BLZ as parentHub3_2_0_, institutsd2_.BLZ as BLZ2_1_, institutsd2_.name as name2_1_, institutsd2_.parentHub_BLZ as parentHub3_2_1_, searchdata3_.id as id1_2_, searchdata3_.fakeContent as fakeCont2_1_2_ from ProfileData profiledat0_ inner join InstitutsData institutsd1_ on profiledat0_.kontaktSparkasse_BLZ=institutsd1_.BLZ left outer join InstitutsData institutsd2_ on institutsd1_.parentHub_BLZ=institutsd2_.BLZ left outer join SearchData searchdata3_ on profiledat0_.searchData_id=searchdata3_.id where profiledat0_.id=?
-------------------- this should be a single SQL statement ? ------------------------
Hibernate: select this_.id as id3_5_, this_.potentialMatch as potentia2_3_5_, this_.searchingProfile as searchin3_3_5_, profiledat1_.id as id0_0_, profiledat1_.firstName as firstName0_0_, profiledat1_.kontaktSparkasse_BLZ as kontaktS5_0_0_, profiledat1_.lastName as lastName0_0_, profiledat1_.profileType as profileT4_0_0_, profiledat1_.searchData_id as searchData6_0_0_, institutsd4_.BLZ as BLZ2_1_, institutsd4_.name as name2_1_, institutsd4_.parentHub_BLZ as parentHub3_2_1_, institutsd5_.BLZ as BLZ2_2_, institutsd5_.name as name2_2_, institutsd5_.parentHub_BLZ as parentHub3_2_2_, searchdata6_.id as id1_3_, searchdata6_.fakeContent as fakeCont2_1_3_, profiledat7_.id as id0_4_, profiledat7_.firstName as firstName0_4_, profiledat7_.kontaktSparkasse_BLZ as kontaktS5_0_4_, profiledat7_.lastName as lastName0_4_, profiledat7_.profileType as profileT4_0_4_, profiledat7_.searchData_id as searchData6_0_4_ from MatchingData this_ inner join ProfileData profiledat1_ on this_.potentialMatch=profiledat1_.id left outer join InstitutsData institutsd4_ on profiledat1_.kontaktSparkasse_BLZ=institutsd4_.BLZ left outer join InstitutsData institutsd5_ on institutsd4_.parentHub_BLZ=institutsd5_.BLZ left outer join SearchData searchdata6_ on profiledat1_.searchData_id=searchdata6_.id inner join ProfileData profiledat7_ on this_.searchingProfile=profiledat7_.id where profiledat1_.firstName=?
Hibernate: select institutsd0_.BLZ as BLZ2_1_, institutsd0_.name as name2_1_, institutsd0_.parentHub_BLZ as parentHub3_2_1_, institutsd1_.BLZ as BLZ2_0_, institutsd1_.name as name2_0_, institutsd1_.parentHub_BLZ as parentHub3_2_0_ from InstitutsData institutsd0_ left outer join InstitutsData institutsd1_ on institutsd0_.parentHub_BLZ=institutsd1_.BLZ where institutsd0_.BLZ=?
Hibernate: select searchdata0_.id as id1_0_, searchdata0_.fakeContent as fakeCont2_1_0_ from SearchData searchdata0_ where searchdata0_.id=?
Hibernate: select searchdata0_.id as id1_0_, searchdata0_.fakeContent as fakeCont2_1_0_ from SearchData searchdata0_ where searchdata0_.id=?
-------------------- this should be a a single SQL statement ? ------------------------
Hibernate: select this_.id as id3_5_, this_.potentialMatch as potentia2_3_5_, this_.searchingProfile as searchin3_3_5_, profiledat2_.id as id0_0_, profiledat2_.firstName as firstName0_0_, profiledat2_.kontaktSparkasse_BLZ as kontaktS5_0_0_, profiledat2_.lastName as lastName0_0_, profiledat2_.profileType as profileT4_0_0_, profiledat2_.searchData_id as searchData6_0_0_, institutsd3_.BLZ as BLZ2_1_, institutsd3_.name as name2_1_, institutsd3_.parentHub_BLZ as parentHub3_2_1_, institutsd4_.BLZ as BLZ2_2_, institutsd4_.name as name2_2_, institutsd4_.parentHub_BLZ as parentHub3_2_2_, searchdata5_.id as id1_3_, searchdata5_.fakeContent as fakeCont2_1_3_, profiledat6_.id as id0_4_, profiledat6_.firstName as firstName0_4_, profiledat6_.kontaktSparkasse_BLZ as kontaktS5_0_4_, profiledat6_.lastName as lastName0_4_, profiledat6_.profileType as profileT4_0_4_, profiledat6_.searchData_id as searchData6_0_4_ from MatchingData this_ inner join ProfileData profiledat2_ on this_.potentialMatch=profiledat2_.id left outer join InstitutsData institutsd3_ on profiledat2_.kontaktSparkasse_BLZ=institutsd3_.BLZ left outer join InstitutsData institutsd4_ on institutsd3_.parentHub_BLZ=institutsd4_.BLZ left outer join SearchData searchdata5_ on profiledat2_.searchData_id=searchdata5_.id inner join ProfileData profiledat6_ on this_.searchingProfile=profiledat6_.id
Hibernate: select institutsd0_.BLZ as BLZ2_1_, institutsd0_.name as name2_1_, institutsd0_.parentHub_BLZ as parentHub3_2_1_, institutsd1_.BLZ as BLZ2_0_, institutsd1_.name as name2_0_, institutsd1_.parentHub_BLZ as parentHub3_2_0_ from InstitutsData institutsd0_ left outer join InstitutsData institutsd1_ on institutsd0_.parentHub_BLZ=institutsd1_.BLZ where institutsd0_.BLZ=?
Hibernate: select searchdata0_.id as id1_0_, searchdata0_.fakeContent as fakeCont2_1_0_ from SearchData searchdata0_ where searchdata0_.id=?
Hibernate: select searchdata0_.id as id1_0_, searchdata0_.fakeContent as fakeCont2_1_0_ from SearchData searchdata0_ where searchdata0_.id=?
据我所知:HQL查找本身不会进行急切的提取,而是通过个别选择加载ProfileData(和更多数据)。当然,我可以添加一些Eager Fetching Hints,但这在复杂的数据结构中非常麻烦。
Criteria Query设法在一个语句中连同其SearchData一起加载一方(potentialMatch)。另一方面(searchingProfile)也被提取,但是下级实体(SearchData和其他元素)随后被显式选择提取。
问题:是否有一种优雅的方法可以确保在一个swift中加载数据?