1

1200万を超える行を含むテーブルがあります。

Lucene.NETを使用してこの行にインデックスを付ける必要があります(最初のインデックスを実行する必要があります)。

そこで、SQLからバッチパケットを読み取ることにより、バッチ方式でインデックスを作成しようとします(バッチあたり1000行)。

外観は次のとおりです。

public void BuildInitialBookSearchIndex()
{
            FSDirectory directory = null;
            IndexWriter writer = null;

            var type = typeof(Book);

            var info = new DirectoryInfo(GetIndexDirectory());

            //if (info.Exists)
            //{
            //    info.Delete(true);
            //}

            try
            {
                directory = FSDirectory.GetDirectory(Path.Combine(info.FullName, type.Name), true);
                writer = new IndexWriter(directory, new StandardAnalyzer(), true);
            }
            finally
            {
                if (directory != null)
                {
                    directory.Close();
                }

                if (writer != null)
                {
                    writer.Close();
                }
            }

            var fullTextSession = Search.CreateFullTextSession(Session);

            var currentIndex = 0;
            const int batchSize = 1000;

            while (true)
            {
                var entities = Session
                    .CreateCriteria<BookAdditionalInfo>()
                    .CreateAlias("Book", "b")
                    .SetFirstResult(currentIndex)
                    .SetMaxResults(batchSize)
                    .List();

                using (var tx = Session.BeginTransaction())
                {
                    foreach (var entity in entities)
                    {
                        fullTextSession.Index(entity);
                    }

                    currentIndex += batchSize;

                    Session.Flush();
                    tx.Commit();
                    Session.Clear();
                }

                if (entities.Count < batchSize)
                    break;
     }
}

ただし、現在のインデックスが600〜700万を超えると、操作はタイムアウトになります。NHibernatePaggingはタイムアウトをスローします。

この1200万行にインデックスを付けるためのNHibernateの他の方法はありますか?

編集:

おそらく私は最も農民の解決策を実行します。

BookIdは私のテーブルのクラスターインデックスであり、selectはBookIdによって非常に高速に発生するため、最大のBookIdを見つけてすべてのレコードを調べ、それらすべてにインデックスを付けます。

for (long = 0; long < maxBookId; long++)
{
   // get book by bookId
   // if book exist, index it
}

他にご提案がございましたら、この質問にご返信ください。

4

1 に答える 1

2

データセット全体をページングする代わりに、分割統治を試みることができます。書籍IDにインデックスがあるとおっしゃいましたが、bookidの範囲に従って書籍のバッチを返すように条件を変更するだけです。

var entities = Session
    .CreateCriteria<BookAdditionalInfo>()
    .CreateAlias("Book", "b")
    .Add(Restrictions.Gte("BookId", low))
    .Add(Restrictions.Lt("BookId", high))
    .List();

低と高が0-1000、1001-2000などのように設定されている場合

于 2012-05-15T09:46:42.170 に答える