2

プログラムの起動時に、遅延読み込みではなく、データベース全体の完全なオブジェクト グラフをドメイン オブジェクトに読み込みます。これが典型的な使用法ではないことは理解していますが、それは問題外です。データベースは、単一のユーザー/プログラムによってのみアクセスされます。そして、次の条件は、この単一の起動負荷操作に関するものです。

データベースが大きくなるにつれて、ロード時間はかなりの量になります。これらの数値は、同じデータベースの 2 つの州に対応しています。

1. Size 1.6MB, 3 main tables row count; 1100, 2400, 13400. Load time;    44s
2. Size 3.6MB, 3 main tables row count; 2800, 6200, 26700. Load time; 3m 40s

3 つのテーブルにはこれらの列があります。

7x integer, 4x numeric, 6x text, 2x datetime  (2800 rows)
7x integer, 3x numeric, 11x text, 2x datetime (6200 rows)
4x integer, 2x numeric, 5x text, 1x datetime  (26700 rows)

すべてのマッピングは1:m.

CPU プロファイラーはこれを示します。http://img585.imageshack.us/img585/4444/6rh.png

アドバイスをいただければ幸いです。

  1. この状態で(非常に大まかに)予想される/目標とされるロード時間はどれくらいですか? これらの時間は合理的ですか、それとも完全にチャートから外れていますか?
  2. ボトルネックは何ですか?
  3. 別のデータベースの方がパフォーマンスが向上する可能性がありますか? (どれの?)
  4. 読み込み時間を改善するための関連する提案

編集:

マッピング;

   public class AccountBaseMap : ClassMap<AccountBase>
    {
       public AccountBaseMap()
           : base()
       {
           Id(x => x.Id).GeneratedBy.Identity();      
           HasMany(x => x.Executions).KeyColumn("Account__Id").Cascade.All();
           HasMany(x => x.Orders).KeyColumn("Account__Id").Cascade.All();
           //...value types omitted                 
           References(x => x.RiskProfile).Cascade.All();                
       }
   }

   public class LocalOrderMap : ClassMap<LocalOrder>
    {
       public LocalOrderMap()
            : base()
        {
            Id(x => x.Id).GeneratedBy.Identity();
            Map(x => x.Account__Id);    
            //...value types omitted       
            HasMany(x => x.StatusDetails).KeyColumn("Order__id").Cascade.All(); 
        }
  }

    public class OrderStatusDetailMap : ClassMap<OrderStatusDetail>
    {
       public OrderStatusDetailMap()
            : base()
        {
            Id(x => x.Id).GeneratedBy.Identity();
            //...value types omitted         
            Map(x => x.Order__Id); 
            Map(x => x.Time).CustomType("timestamp");                 
        }
     }

Hibernate ShowSql、クエリから;

_session.CreateCriteria(T)().List(T)();

出力; (約1000行でした、同様に.....で削除されました)

http://textuploader.com/?p=6&id=ie7mn


編集2:

Hibernate 構成;

 var fcfg = Fluently.Configure()
     .Database(SQLiteConfiguration.Standard.ConnectionString(connString)); 

 fcfg.Mappings(m => m.FluentMappings.AddFromAssemblyOf<TMap1>().Conventions.Add(FluentNHibernate.Conventions.Helpers.DefaultLazy.Never()));

if (typeof(TMap1) != typeof(TMap2))
    fcfg.Mappings(m => m.FluentMappings.AddFromAssemblyOf<TMap2>().Conventions.Add(FluentNHibernate.Conventions.Helpers.DefaultLazy.Never()));

fcfg.ExposeConfiguration(c => cfg = c).Cache(c => c.UseQueryCache());

sessionFactory = fcfg.BuildSessionFactory();

私はロギング フレームワークを使用していないので、ロギングをオンにする必要はないと考えています。現在、デバッグ ビルドを実行していますが、リリース ビルドで違いが生じるかどうかを確認します。

建築について; ソリューションは任意の CPU に設定され、プロジェクトは x86 (プラットフォーム ターゲット) にビルドされます。x86 XP と x64 Windows 7 の両方で実行し、それに基づいて正しい System.Data.SQLite.dll をロードします。

ところで、私は使用していますNHibernate 3.1.0.4

4

3 に答える 3

0

いくつかの提案/質問

  • すべてのロギングをオフにしてみてください。
  • SQLite に正しい x86/x64 アーキテクチャを使用していますか?
  • NH 構成はどのように見えますか?
  • 正しい SQLite NH ドライバーを使用していることを確認してください。
  • default_schemaプロパティを設定していますか?
  • すべてのリクエストに対してSessionFactoryを作成していますか?

そして、他のすべてが失敗した場合:

  • SQL CE 4 を試す

NHibernate (特に 3.x 以降) ですべてをログに記録すると、デバッグ時に重大なパフォーマンスの問題が発生する可能性があります。

于 2013-07-31T00:02:32.697 に答える
0

最後に、変更する必要があるのは 1 つだけであることがわかりました。

クラス マップで、すべての 1:M コレクションに追加Fetch.Subselect()

HasMany(x => x.Orders)。Fetch.Subselect() .KeyColumn("Account__Id").Not.LazyLoad().Cascade.All().Inverse();

(そこにも追加しましNot.LazyLoad()たが、違いはないので省略できます)

この変更により、流暢な構成規則を維持できますDefaultLazy.Never。これは、プロパティとメソッドを仮想化する必要がないため良いことです。そして、一方向の関係を保つことができます。基本的に、この詳細を超えて以前のコードに変更や特別な調整はありません。

現在のデータベースの読み込み時間は、現在 4.8 MB で、11 分から 13 秒に短縮されました。

于 2013-09-02T23:16:46.357 に答える