0

10 秒ごとに 300 件のクエリ (全文検索) を処理できる必要があるデータベース (RavenDB) があります。パフォーマンスを向上させるために、データベースを分割して、コードに複数の documentStores を用意しました。

            var watch = Stopwatch.StartNew();
        int taskcnt = 0;
        int sum = 0;


        for (int i = 0; i < 11; i++)
        {
            Parallel.For(0, 7, new Action<int>((x) =>
            {
                for(int docomentStore = 0;docomentStore < 5; docomentStore++)
                {
                    var stopWatch = Stopwatch.StartNew();
                    Task<IList<eBayItem>> task = new Task<IList<eBayItem>>(Database.ExecuteQuery, new Filter()
                    {
                        Store = "test" + docomentStore,
                        MaxPrice = 600,
                        MinPrice = 200,
                        BIN = true,
                        Keywords = new List<string>() { "Canon", "MP", "Black" },
                        ExcludedKeywords = new List<string>() { "G1", "T3" }
                    });
                    task.ContinueWith((list) => {
                        stopWatch.Stop();
                        sum += stopWatch.Elapsed.Milliseconds;
                        taskcnt++;
                        if (taskcnt == 300)
                        {
                            watch.Stop();
                            Console.WriteLine("Average time: " + (sum / (float)300).ToString());
                            Console.WriteLine("Total time: " + watch.Elapsed.ToString() + "ms");

                        }

                    });
                    task.Start();
                }

            }));
            Thread.Sleep(1000);

        }
  • 平均クエリ時間: 514.13 ミリ秒
  • 合計時間: 00:01:29.9108016

ravenDB にクエリを実行するコード:

        public static IList<eBayItem> ExecuteQuery(object Filter)
    {
        IList<eBayItem> items;
        Filter filter = (Filter)Filter;

        if (int.Parse(filter.Store.ToCharArray().Last().ToString()) > 4)
        {
            Console.WriteLine(filter.Store); return null;
        }
        using (var session = Shards[filter.Store].OpenSession())
        {
            var query = session.Query<eBayItem, eBayItemIndexer>().Where(y => y.Price <= filter.MaxPrice && y.Price >= filter.MinPrice);

            query = filter.Keywords.ToArray()
            .Aggregate(query, (q, term) =>
                q.Search(xx => xx.Title, term, options: SearchOptions.And));
            if (filter.ExcludedKeywords.Count > 0)
            {
                query = filter.ExcludedKeywords.ToArray().Aggregate(query, (q, exterm) =>
                q.Search(it => it.Title, exterm, options: SearchOptions.Not));
            }
            items = query.ToList<eBayItem>();
        }
        return items;
    }

RavenDB の初期化:

        static Dictionary<string, EmbeddableDocumentStore> Shards = new Dictionary<string, EmbeddableDocumentStore>();
    public static void Connect()
    {
        Shards.Add("test0", new EmbeddableDocumentStore() { DataDirectory = "test.db" });
        Shards.Add("test1", new EmbeddableDocumentStore() { DataDirectory = "test1.db" });
        Shards.Add("test2", new EmbeddableDocumentStore() { DataDirectory = "test2.db" });
        Shards.Add("test3", new EmbeddableDocumentStore() { DataDirectory = "test3.db" });
        Shards.Add("test4", new EmbeddableDocumentStore() { DataDirectory = "test4.db" });
        foreach (string  key in Shards.Keys)
        {
            EmbeddableDocumentStore store = Shards[key];
            store.Initialize();
            IndexCreation.CreateIndexes(typeof(eBayItemIndexer).Assembly, store);
        }
    }

合計時間が短くなるようにコードを最適化するにはどうすればよいですか? データベースを 5 つの異なるデータベースに分割するのは良いことですか?

編集:プログラムには、5 ではなく 1 つの documentStore しかありませ

Price_Range:[* TO Dx600] AND Price_Range:[Dx200 TO NULL] AND Title:(Canon) AND Title:(MP) AND Title:(Black) -Title:(G1) -Title:(T3)
4

2 に答える 2