Я столкнулся с проблемами производительности при получении отфильтрованных данных в небольшой локальной базе данных. Я уменьшил код (как показано ниже), чтобы воспроизвести проблему. Выходной сигнал составляет около 2000 мс.MongoDb C# Driver - Получить элемент по индексированному полю очень медленно
Некоторая дополнительная информация:
- Запрашиваемый коллекция содержит 135000 записей с 7 простых типов каждый
- При выполнении аналогичного запроса в чем-то вроде RoboMongo - db.TickerData.find ({_ ид : ObjectId ('5731d39062deb83134772e77')}). Explain() - totalExecutionTime is < 1ms
- Я использую новейшие версии сервера MongoDb и версии C#
- База данных работает локально (четырехъядерный 16Mb Ram) в той же среде dev/debug
- Я не заметил разницы в производительности между индексированными и не проиндексированными полями при тестировании в других полях, кроме ID (который всегда индексируется)
- Мой первый, хотя в том, что операция LINQ Одиночная() возвращает все документы, прежде чем сделать один поиск, но из Google'ing, кажется, что все операции LINQ Транспонирование на стороне сервера MongoDB запросов
Код:
public class UnitTest1
{
public void TestMethod2()
{
Stopwatch sw = new Stopwatch();
sw.Start();
new BaseRepository<TickerData>().GetById("5731d39062deb83134772e77");
sw.Stop();
Debug.Write(sw.Elapsed.TotalMilliseconds);
}
}
public class BaseRepository<T> : MongoBase where T : BaseEntity
{
MongoDatabase DataBase { get; set; }
protected IQueryable<T> Collection { get; set; }
MongoCollection<BsonDocument> mCollection { get; set; }
public BaseRepository()
{
DataBase = Server.GetDatabase("TradingBot");
mCollection = DataBase.GetCollection<BsonDocument>(typeof(T).Name);
Collection = mCollection.AsQueryable<T>();
}
public T GetById(string ID)
{
return Collection.Single(i => i.Id.ToString() == ID);
}
}
Обновление: Рекомендовать в соответствии с @rnofenko (см. Комментарии), сделало огромное улучшение, но все еще кажется способ замедлить работу?
Преобразование типа в 'GetById' выглядит обратным образом, что может помешать использованию индекса. Можете ли вы попробовать 'Collection.Single (i => i.Id == new ObjectId (ID)); вместо этого? – JohnnyHK
Да, вы правы, что моя реализация ToString была неправильной. Однако использование SingleAsync в соответствии с решением @ mofenko в любом случае помешало мне использовать ToString на Id. Таким образом, использование было уже правильным, и его выполнение слишком медленно при 500-600 мс. – Pierre
ОК. [MCVE] (http://stackoverflow.com/help/mcve) действительно поможет здесь, так как я не могу воспроизвести то, что вы видите, и ваш примерный код не является полным. – JohnnyHK