我已使用solution = solution.WithDocumentText(currentDocument.Id,
currentDocumentSyntaxTree.GetText());
在webapi
创建了一个小项目。我有一个控制器和一个插入,更新和读取文档的存储库。为了测试这一点,我创建了一个.net core 2.0
测试来创建,更新和读取项目,并使用20个并行线程启动它。问题是有时,读取操作或更新操作需要4秒钟。这是我的代码:
jmeter
来自startup.cs的代码:
public class TransactionRepository : ITransactionRepository
{
private readonly MongoClient _mongoClient;
public TransactionRepository(string connectionString)
{
_mongoClient = new MongoClient(connectionString);
}
public async Task<TransactionResponse> RetrieveResponse(string id)
{
using (IAsyncCursor<TransactionRequest> cursor = await this._mongoClient
.GetDatabase("MyDatabase")
.GetCollection<TransactionRequest>("Transactions")
.FindAsync(t => t.Transaction.Id.Equals(id)))
{
while (await cursor.MoveNextAsync())
{
IEnumerable<TransactionRequest> documents = cursor.Current.ToList();
if (documents.Any())
{
var request = documents.First();
return new TransactionResponse { InternalId = request._id.ToString(), TransactionId = request.Transaction.Id};
}
Console.WriteLine(documents.Count());
}
}
return null;
}
public async Task<TransactionResponse> SaveAsync(TransactionRequest request)
{
await this._mongoClient
.GetDatabase("MyDatabase")
.GetCollection<TransactionRequest>("Transactions")
.InsertOneAsync(request, null, CancellationToken.None);
return new TransactionResponse
{
InternalId = request._id.ToString(),
TransactionId = request.Transaction.Id
};
}
public async Task<TransactionResponse> UpdateAsync(TransactionRequest request)
{
var findFilter = Builders<TransactionRequest>.Filter.Eq(t => t.Transaction.Id, request.Transaction.Id);
var updateSettings = Builders<TransactionRequest>
.Update
.Set(t => t.Transaction.Status, request.Transaction.Status)
.Set(t => t.Header.BusinessId, request.Header.BusinessId);
var findOptions = new FindOneAndUpdateOptions<TransactionRequest>
{
ReturnDocument = ReturnDocument.Before
};
var updatedRecord = await this._mongoClient
.GetDatabase("MyDatabase")
.GetCollection<TransactionRequest>("Transactions")
.FindOneAndUpdateAsync(
findFilter,
updateSettings,
findOptions);
string internalid = updatedRecord == null ? "-1" : updatedRecord._id.ToString();
string transactionId = updatedRecord == null ? "-1" : updatedRecord.Transaction.Id;
return new TransactionResponse {TransactionId = transactionId, InternalId = internalid };
}
}
控制器代码:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddTransient<ITransactionRepository, TransactionRepository>(option => new TransactionRepository(Configuration["ConnectionString"]));
}
以下是我的模特课程:
[Route("api/requests")]
public class RequestsController : Controller
{
private readonly ITransactionRepository _repository;
public RequestsController(ITransactionRepository repository)
{
this._repository = repository;
}
[HttpPost]
[Route("")]
public async Task<TransactionResponse> Add([FromBody]TransactionRequest request)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var result = await this._repository.SaveAsync(request);
stopwatch.Stop();
Trace.WriteLine("#Trace# inserted item: " + stopwatch.ElapsedMilliseconds);
return result;
}
[HttpPost]
[Route("update")]
public async Task<TransactionResponse> Update([FromBody]TransactionRequest request)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var result = await this._repository.UpdateAsync(request);
stopwatch.Stop();
Trace.WriteLine("#Trace# updated item: " + stopwatch.ElapsedMilliseconds);
return result;
}
[HttpGet]
[Route("{id}")]
public async Task<TransactionResponse> Get([FromRoute]string id)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var result = await this._repository.RetrieveResponse(id);
stopwatch.Stop();
Trace.WriteLine("#Trace# read item: " + stopwatch.ElapsedMilliseconds);
return result;
}
}
我是否需要在数据库中创建索引?更新操作或读取操作是否正常,3-4秒?
答案 0 :(得分:0)
我会尽力帮助您,找出问题: 我假设你正在尝试使用最新的MongoDB(3.6)(如果没有,请告诉我,可能你有mongo引擎MMAP的问题)。
您需要分析您尝试在数据库级别执行的查询。尝试从终端窗口执行以下命令:
mongo
use MyDatabase
db.setProfilingLevel(2, { slowms: 20 })
执行您的查询(来自应用程序)。之后,您可以查看结果(在同一个终端窗口中):
show profile
它会打印出以下结果(我这里只放了一部分):
query test.products 3ms Thu Jan 18 2018 07:57:36
command:{ "find" : "products", "filter" : { "brand" : "ACME" }, "$db" : "test" } keysExamined:0 docsExamined:11
如您所见,我的请求已在3毫秒内执行,检查的文件数量为11个。
我可以接受我的请求,并查看索引的详细用法:
db.products.find({brand: "ACME"}).explain()
此查询将显示查询是使用COLLSCAN
(基本光标)还是index
(BTree)
在这些操作之后,我们可以找出问题的位置(在代码中或在数据库级别上),以及我们如何解决它。