2012-03-23 48 views
4

我能夠使用嵌入式版本的RavenDb加載幾百萬個文檔,非常漂亮!RavenDb對以百萬爲單位的文檔查詢性能的期望

現在我試圖查詢這些項目,並發現性能不是我所期望的,如果可能的話,幾乎是瞬間的,但是在一臺相當健壯的機器上可以達到18秒。

下面,你會發現我的樸素代碼。

注意:我現在已經解決了這個問題,最終的代碼位於帖子的底部。帶走的是你需要索引,它們必須是正確的類型,並且需要讓RavenDB知道它們。非常滿意通過查詢引擎返回記錄的性能和質量。

謝謝 斯蒂芬

using (var store = new EmbeddableDocumentStore { DataDirectory = @"C:\temp\ravendata" }.Initialize()) 
{ 
    using (IDocumentSession session = store.OpenSession()) 
    { 
     var q = session.Query<Product>().Where(x => x.INFO2.StartsWith("SYS")).ToList(); 
    } 
} 


[Serializable] 
public class Product 
{ 
    public decimal ProductId { get; set; } 
    .... 
    public string INFO2 { get; set; } 
} 

編輯

我加入這個類

public class InfoIndex_Search : AbstractIndexCreationTask<Product> 
{ 
    public InfoIndex_Search() 
    { 
     Map = products => 
      from p in products 
          select new { Info2Index = p.INFO2 }; 

     Index(x => x.INFO2, FieldIndexing.Analyzed); 
    } 
} 

,改變調用方法看起來像這樣。

 using (var store = new EmbeddableDocumentStore { DataDirectory = @"C:\temp\ravendata" }.Initialize()) 
     { 
      // Tell Raven to create our indexes. 
      IndexCreation.CreateIndexes(Assembly.GetExecutingAssembly(), store); 

      List<Product> q = null; 
      using (IDocumentSession session = store.OpenSession()) 
      { 
       q = session.Query<Product>().Where(x => x.INFO2.StartsWith("SYS")).ToList(); 
       watch.Stop(); 
      } 
     } 

但我仍然報告18秒做搜索。我錯過了什麼?在另一個說明中,C:\ temp \ ravendata \ Indexes \ InfoIndex%2fSearch文件夾中有很多新文件,雖然不像插入數據時那麼多,但它們在運行此代碼後似乎都消失了幾次嘗試查詢。如果IndexCreation.CreateIndexes(Assembly.GetExecutingAssembly(),store);在插入之前調用,只有這樣?

EDIT1

使用此代碼我能得到查詢的一個實例幾乎要發生,但似乎你只能運行一次此,這樣引出了一個問題。在哪裏運行,什麼是正確的初始化程序?

store.DatabaseCommands.PutIndex("ProdcustByInfo2", new IndexDefinitionBuilder<Product> 
{ 
    Map = products => from product in products 
         select new { product.INFO2 }, 
    Indexes = 
      { 
       { x => x.INFO2, FieldIndexing.Analyzed} 
      } 
}); 

EDIT2:工作示例

static void Main() 
{ 
    Stopwatch watch = Stopwatch.StartNew(); 

    int q = 0; 
    using (var store = new EmbeddableDocumentStore { DataDirectory = @"C:\temp\ravendata" }.Initialize()) 
    { 
     if (store.DatabaseCommands.GetIndex("ProdcustByInfo2") == null) 
     { 
      store.DatabaseCommands.PutIndex("ProdcustByInfo2", new IndexDefinitionBuilder<Product> 
      { 
       Map = products => from product in products 
            select new { product.INFO2 }, 
       Indexes = { { x => x.INFO2, FieldIndexing.Analyzed } } 
      }); 
     } 
     watch.Stop(); 
     Console.WriteLine("Time elapsed to create index {0}{1}", watch.ElapsedMilliseconds, System.Environment.NewLine); 

     watch = Stopwatch.StartNew();    
     using (IDocumentSession session = store.OpenSession()) 
     { 
      q = session.Query<Product>().Count(); 
     } 
     watch.Stop(); 
     Console.WriteLine("Time elapsed to query for products values {0}{1}", watch.ElapsedMilliseconds, System.Environment.NewLine); 
     Console.WriteLine("Total number of products loaded: {0}{1}", q, System.Environment.NewLine); 

     if (q == 0) 
     { 
      watch = Stopwatch.StartNew(); 
      var productsList = Parsers.GetProducts().ToList(); 
      watch.Stop(); 
      Console.WriteLine("Time elapsed to parse: {0}{1}", watch.ElapsedMilliseconds, System.Environment.NewLine); 
      Console.WriteLine("Total number of items parsed: {0}{1}", productsList.Count, System.Environment.NewLine); 

      watch = Stopwatch.StartNew(); 
      productsList.RemoveAll(_ => _ == null); 
      watch.Stop(); 
      Console.WriteLine("Time elapsed to remove null values {0}{1}", watch.ElapsedMilliseconds, System.Environment.NewLine); 
      Console.WriteLine("Total number of items loaded: {0}{1}", productsList.Count, System.Environment.NewLine); 

      watch = Stopwatch.StartNew(); 
      int batch = 0; 
      var session = store.OpenSession(); 
      foreach (var product in productsList) 
      { 
       batch++; 
       session.Store(product); 
       if (batch % 128 == 0) 
       { 
        session.SaveChanges(); 
        session.Dispose(); 
        session = store.OpenSession(); 
       } 
      } 
      session.SaveChanges(); 
      session.Dispose(); 
      watch.Stop(); 
      Console.WriteLine("Time elapsed to populate db from collection {0}{1}", watch.ElapsedMilliseconds, System.Environment.NewLine); 
     } 

     watch = Stopwatch.StartNew(); 
     using (IDocumentSession session = store.OpenSession()) 
     { 
      q = session.Query<Product>().Where(x => x.INFO2.StartsWith("SYS")).Count(); 
     } 
     watch.Stop(); 
     Console.WriteLine("Time elapsed to query for term {0}{1}", watch.ElapsedMilliseconds, System.Environment.NewLine); 
     Console.WriteLine("Total number of items found: {0}{1}", q, System.Environment.NewLine); 
    } 
    Console.ReadLine(); 
} 
+0

你有一個涵蓋INFO2的指數嗎? – 2012-03-23 16:38:20

+0

我現在在做什麼..旅程是多麼有趣,但非常值得。 – 2012-03-24 14:24:38

回答

6

首先,你必須覆蓋INFO2的指數?

其次,看到丹尼爾郎鹹平的「搜索在RavenDB字符串屬性」此處的博客文章:

http://daniellang.net/searching-on-string-properties-in-ravendb/

如果有幫助,這裏就是我創建的索引:

public class LogMessageCreatedTime : AbstractIndexCreationTask<LogMessage> 
{ 
    public LogMessageCreatedTime() 
    { 
     Map = messages => from message in messages 
          select new { MessageCreatedTime = message.MessageCreatedTime }; 
    } 
} 

又如何我在運行時添加了它:

private static DocumentStore GetDatabase() 
{    
    DocumentStore documentStore = new DocumentStore();    

    try 
    { 
     documentStore.ConnectionStringName = "RavenDb";     
     documentStore.Initialize(); 

     // Tell Raven to create our indexes. 
     IndexCreation.CreateIndexes(typeof(DataAccessFactory).Assembly, documentStore); 
    } 
    catch 
    { 
     documentStore.Dispose(); 
     throw; 
    } 

    return documentStore; 
} 

就我而言,我不必明確查詢索引;當我正常查詢時才使用它。

+1

是的,我昨天在另一篇文章中遇到丹尼爾,然後搜索了一些東西,他的網站出現了。閱讀大部分烏鴉標記的帖子。除了缺少文檔之外,外賣是自動完成索引的,而不是猜測。 – 2012-03-23 17:29:57

+0

有動態索引,它是根據用途自動創建的,但這些實際上只是一個權宜之計,或者對於小型數據庫(在我看來)。他們讓你快速啓動並使用安全的默認設置。 – 2012-03-23 17:40:52

+0

我在我的答案中添加了一些代碼。希望能幫助到你。 – 2012-03-23 17:56:02

0

正如Bob所暗示的那樣,您應該確保您在Raven中創建了涵蓋您打算查詢的字段的索引。

烏鴉非常快,可以讓你走很長的路,而不需要做太多。 然而,一旦你開始進入大文件號碼,或者需要非默認的東西,你會發現你需要靜態索引。

在Raven中有很多關於設置和使用索引的示例。

+0

謝謝。你能否指點我一些文檔來說明正確的索引創建和後續查詢這些索引? – 2012-03-23 17:33:22

+1

我不確定'官方'文檔(我在平板電腦上atm,所以看起來有點困難),但我寫了一篇博客文章,演示在Raven http://will.hughesfamily.net上創建和安裝索引。 .au/20101212/ravendb-map-reduce-indexes-and-how-to-install-them/- 希望有所幫助(只需忽略'reduce'位) – 2012-03-23 17:45:20

+0

另外,Bob鏈接的博客文章給出了一個很好的例子的Map語句,以及如何使用它們。 – 2012-03-23 17:46:45

相關問題