使用C#从MongoDb响应缓慢

安杜里尔

我最近一直在努力建立一个Mongo数据库服务器,以充当网站的对象缓存。但是,在完成所有设置后,我担心性能会很慢。

它是单个服务器,不属于副本集或分片。我正在从本地计算机到Windows Azure VM上的服务器运行所有测试。

例如,我收集了大约5500个文档,其中每个文档都存储一个指向外部站点的链接。一个典型的文档如下所示:

{ 
    "_id" : 5001 , 
    "Active" : true , 
    "CategoryId" : 1 , 
    "Crci" : "V" , 
    "CultureId" :  null,
    "DateUpdated" : { "$date" : 1333370987810} ,
    "Description" : "National Careers Service: Childminder" ,
    "Keywords" :  null ,
    "MaxLevel" :  null ,
    "MinLevel" :  null ,
    "PhoneNumber" :  null ,
    "Priority" : 1 , 
    "Title" : "National Careers Service: Childminder" ,
    "WebUrl" : "https://nationalcareersservice.direct.gov.uk/advice/planning/jobprofiles/Pages/childminder.aspx"
}

我使用10gen官方驱动程序从代码中尝试了以下示例查询,平均花费2.7-3.0秒完成:

var query = (from er in lib.All()
             where er.Id > 7000
             select er);

(lib是一个瘦包装器类,All()公开IQuerable接口)

上面的查询返回大约3000条记录。

我检查了由linq生成的查询,这似乎很好:

{_id: { $gt: 7000} }

从umongo(GUI界面)运行相同的查询将在不到一秒钟的时间内返回结果,这比我期望的要多。

使用确保索引正确地为字段建立索引(填充集合时称为一次,此后为只读数据:

collection.EnsureIndex(new IndexKeysBuilder<ExternalResourceView>().Ascending(er => er.Id), IndexOptions.SetUnique(true));
collection.EnsureIndex(new IndexKeysBuilder<ExternalResourceView>().Ascending(er => er.CategoryId));
collection.EnsureIndex(new IndexKeysBuilder<ExternalResourceView>().Ascending(er => er.Active));
collection.EnsureIndex(new IndexKeysBuilder<ExternalResourceView>().Ascending(er => er.Keywords));

该索引似乎用于搜索:

db.ExternalResources.find({_ id:{$ gt:7000}})。explain()

{
        "cursor" : "BtreeCursor _id_",
        "isMultiKey" : false,
        "n" : 3087,
        "nscannedObjects" : 3087,
        "nscanned" : 3087,
        "nscannedObjectsAllPlans" : 3087,
        "nscannedAllPlans" : 3087,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 5,
        "indexBounds" : {
                "_id" : [
                        [
                                7000,
                                1.7976931348623157e+308
                        ]
                ]
        },
        "server" : <Server Name>
}

甚至单次直接ID查找也需要近100毫秒的时间才能返回代码,例如:

 from er in lib.All()
 where er.Id == 3100
 select er

我是否缺少任何设置可以加快搜索速度,或者一开始我的期望不切实际?

编辑:我已经尝试过完全重建/重新填充数据库,但是它仍然感觉缓慢得令人无法接受

编辑2:我将包装器类全部包含在内。我认为这没有错,但以防万一:

public abstract class MongoLibrary<TViewModel> : ILibrary<TViewModel> where TViewModel : class
{
    private readonly MongoCollection _collection;
    private readonly string _dbName;
    private readonly string _collectionName;
    private readonly string _connString;

    protected MongoLibrary(string connString, string dbName, string collectionName)
    {
        _connString = connString;
        connString += "/" + dbName;
        var client = new MongoClient(connString);
        _dbName = dbName;
        _collectionName = collectionName;
        var db = client.GetServer().GetDatabase(dbName);
        _collection = db.GetCollection<TViewModel>(collectionName);
    }

    public abstract void ConfigureIndex(MongoCollection collection);

    public IQueryable<TViewModel> All()
    {
        return _collection.AsQueryable<TViewModel>();
    }

    public IEnumerable<TViewModel> GetWhere(Func<TViewModel, bool> predicate)
    {
        return _collection.AsQueryable<TViewModel>().Where(predicate);
    }

    protected void PopulateData(IEnumerable<TViewModel> views, int instanceToUpdate)
    {
        var ports = //port numbers hidden for security

        foreach (var port in ports)
        {
            var client = new MongoClient(string.Format("{0}:{1}/{2}", _connString, port, _dbName));

            var db = client.GetServer().GetDatabase(_dbName);
            var coll = db.GetCollection(_collectionName);
            coll.Drop();
            coll.InsertBatch(views);
        }
        ConfigureIndex(_collection);
    }

}

编辑3:服务器日志分析查询到数据库:

该查询只是一个用于演示性能的人工查询。查询是:

        var sw = new Stopwatch();
        sw.Start();
        var temp = _externalResourceLibrary.All().Where(er => er.Id > 7500).ToList();
        sw.Stop();

您可以从经过身份验证的日志中查看,然后分两次进行检索。总共检索到2677个文档。花费的时间为3580毫秒(平均5次运行)

>db.system.profile.find().limit(10).sort( { ts : -1 } ).pretty()  
{
    "op" : "getmore",
    "ns" : "cache.ExternalResources",
    "query" : {
        "_id" : {
            "$gt" : 7500
        }
    },
    "cursorid" : NumberLong("949848842778037962"),
    "ntoreturn" : 0,
    "keyUpdates" : 0,
    "numYield" : 0,
    "lockStats" : {
        "timeLockedMicros" : {
            "r" : NumberLong(9486),
            "w" : NumberLong(0)
        },
        "timeAcquiringMicros" : {
            "r" : NumberLong(4),
            "w" : NumberLong(5)
        }
    },
    "nreturned" : 2576,
    "responseLength" : 1511874,
    "millis" : 9,
    "ts" : ISODate("2014-01-28T10:52:16.125Z"),
    "client" : <ipAddress>,
    "allUsers" : [
                    {
                        "user" : <username>,
                        "userSource" : <dbName>;
                    }
    ],
    "user" : <username>@<dbName>;
}
{
    "op" : "query",
    "ns" : "cache.ExternalResources",
    "query" : {
            "_id" : {
                    "$gt" : 7500
            }
    },
    "cursorid" : NumberLong("949848842778037962"),
    "ntoreturn" : 0,
    "ntoskip" : 0,
    "nscanned" : 102,
    "keyUpdates" : 0,
    "numYield" : 0,
    "lockStats" : {
            "timeLockedMicros" : {
                    "r" : NumberLong(749),
                    "w" : NumberLong(0)
            },
            "timeAcquiringMicros" : {
                    "r" : NumberLong(5),
                    "w" : NumberLong(3)
            }
    },
    "nreturned" : 101,
    "responseLength" : 64013,
    "millis" : 0,
    "ts" : ISODate("2014-01-28T10:52:15.954Z"),
    "client" : <ipAddress>,
    "allUsers" : [
            {
                    "user" : <username>,
                    "userSource" : <dbName>;
            }
    ],
    "user" : <username>@<dbName>;
}
{
    "op" : "command",
    "ns" : "cache.$cmd",
    "command" : {
            "authenticate" : 1,
            "user" : <username>,
            "nonce" : <nonce>;,
            "key" : <key>;
    },
    "ntoreturn" : 1,
    "keyUpdates" : 0,
    "numYield" : 0,
    "lockStats" : {
            "timeLockedMicros" : {
                    "r" : NumberLong(381),
                    "w" : NumberLong(0)
            },
            "timeAcquiringMicros" : {
                    "r" : NumberLong(9),
                    "w" : NumberLong(3)
            }
    },
    "responseLength" : 79,
    "millis" : 0,
    "ts" : ISODate("2014-01-28T10:52:15.938Z"),
    "client" : <ipAddress>,
    "allUsers" : [
            {
                    "user" : <username>,
                    "userSource" : <dbName>
            }
    ],
    "user" : <username>@<dbName>;
}
安杜里尔

问题是由网络延迟引起的

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C#表格绘制缓慢

来自分类Dev

如何使用 koa 生成缓慢的响应?

来自分类Dev

C#使用StreamReader,处理响应流

来自分类Dev

订阅使用SIP巫术C#的响应

来自分类Dev

如何使用 C# 从 Oracle 获取响应?

来自分类Dev

使用c#解析xml响应

来自分类Dev

使用System.Data.SQLite在C#应用中缓慢打开SQLite连接

来自分类Dev

在 c# asp.net 中使用 GridView 缓慢填充数据

来自分类Dev

在AWS上使用THIN的Ruby和Rails响应缓慢

来自分类Dev

使用外部主机名时PHP响应缓慢

来自分类Dev

jQuery对scrollTop()的响应缓慢

来自分类Dev

使用BART的API使用RestSharp C#获得响应

来自分类Dev

使用MongoDB C#查找和修改

来自分类Dev

mongodb C#如何使用BSON文档

来自分类Dev

如何使用C#监听mongoDB的更改

来自分类Dev

使用C#将对象插入mongodb

来自分类Dev

无法使用C#从API获取json响应

来自分类Dev

C#如何使用响应状态代码创建WebException

来自分类Dev

使用SIP魔术师C#进行响应

来自分类Dev

C#使用HttpClient从JSON响应中获取特定对象

来自分类Dev

如何在C#中使用HttpClient读取WebAPI响应

来自分类Dev

无法使用C#从Soap响应获取值

来自分类Dev

C#使用HttpClient从JSON响应中获取特定对象

来自分类Dev

C#如何使用响应状态代码创建WebException

来自分类Dev

使用mongodb缓存json响应

来自分类Dev

为什么此循环运行如此缓慢:c#

来自分类Dev

MongoDB查询异常缓慢

来自分类Dev

MongoDB批量更新缓慢

来自分类Dev

键绑定响应非常缓慢