将内部数据结构用作内存数据库是一种好方法吗?

时间:2016-04-28 05:30:10

标签: c# .net database in-memory-database

我正在开展一个非常小规模的计划,主要是使用单词首字母来搜索完整的字符串和附加的额外信息,包括程序内CRUD操作。由于只有大约10k个字符串需要搜索,我宁愿使用内存中方法来加快搜索速度(因为大多数查询都是SELECT)。

简单地使用像List<myobject> data这样的东西并做这样的事情是一种很好的方法:data.Where((s => s.text.Substring(0,3) == expected));?当我使用这种方法时,我可以做些什么来进行数据库优化(比如索引)吗?

4 个答案:

答案 0 :(得分:3)

<强> TL; DR
我建议评估你的要求。如果使用简单的List<>符合您的要求,并且您对分析应用程序的性能结果感到满意,那么请使用它。如果不考虑使用内存数据库。

数据库快速检索数据的主要原因之一是Index。使用常见的C#数据结构时,您会错过此功能。我想如果你正在处理少量记录,那么你就不会遇到性能问题,但是如果你有很多记录,那么你应该考虑使用in memory databases。 请记住,所选数据库可能不支持您希望索引数据的方式,或者您有复杂的查询,索引不会提高其性能。

如果您只有密钥和相应的值,请查看RedisStackExchange.Redis

要考虑的另一件事是并发性!数据库通常支持从多个线程访问数据并在同一数据上处理多个读取器或写入器。您可以使用thread-safe collections in .NET,但必须做很多工作才能获得构建在数据库中的功能。

答案 1 :(得分:2)

如果你只进行前缀搜索(如问题所示),你可以使用列表,只要你保持排序并进行二分搜索而不是线性搜索(这就是{{1}会做的。)

字典,虽然如果你正在做精确匹配要快得多,但这里不是正确的工具,因为你想做的搜索仍然是O(N)。

如果你想使用LINQ,你最好只使用EF和SQL Server CE。这是一个非常轻松的选择,尽管你显然添加了一些重要的依赖项。

如果你想在C#中推出你自己的解决方案,它的工作方式与你正在寻找的数据结构的数据结构大致相同[1]这仍然不会给你LINQ(除非你写一个一堆更多的代码)但会给你很好的搜索性能。

[1] https://en.wikipedia.org/wiki/Trie

答案 2 :(得分:1)

如果您正在使用数据结构,那么最好使用复杂度为o(1)的数据结构,如字典哈希表,而不是列表复杂性更慢。请注意,列表会带给您一些免费记忆。

答案 3 :(得分:1)

检查此测试:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace CSharpConsoleApplication.Tests
{
    class JustATest
    {
        public static void Run()
        {
            var list = new List<Test>();

            for (int i = 0; i < 1000000; i++)
                list.Add(new Test() { Text = "a" + i.ToString().PadLeft(6, '0') });


            string input = "a011";
            List<Test> found = null;




            // Get the results with LinQ

            var w = new Stopwatch(); w.Start();
            found = list.Where(t => t.Text.Substring(0, 4) == input).ToList();
            w.Stop();
            Console.WriteLine("Search list with linq. Results count = {0}", found.Count);
            Console.WriteLine(w.Elapsed);
            Console.ReadLine();




            // Store data in dictionary if no refresh needed

            // Populate the dictionary
            var objectsDictionary = new Dictionary<string, List<Test>>();

            w.Restart();
            PopulateDictionary(objectsDictionary, list, input.Length);
            w.Stop();
            Console.WriteLine("Populate dictionary");
            Console.WriteLine(w.Elapsed);
            Console.ReadLine();

            // Search in dictionary
            w.Restart();
            if (objectsDictionary.ContainsKey(input))
                found = objectsDictionary[input];
            //objectsDictionary[input].ForEach(t => Console.WriteLine(t.Text));

            w.Stop();
            Console.WriteLine("Search in dictionary. Results count = {0}", found.Count);
            Console.WriteLine(w.Elapsed);
            Console.ReadLine();
        }

        static void PopulateDictionary(Dictionary<string, List<Test>> dictionary, List<Test> list, int textLength)
        {
            foreach (var t in list)
            {
                string text = t.Text.Substring(0, textLength);

                if (dictionary.ContainsKey(text))
                    dictionary[text].Add(t);
                else
                    dictionary.Add(text, new List<Test>() { t });
            }
        }

        class Test
        {
            public string Text { get; set; }
        }

    }
}