RavenDB を使用する WPF アプリケーションがあります。ウィンドウの 1 つで、[更新] ボタンを繰り返し押してグリッドを更新できます。更新ごとに RavenDB クエリが発生します。奇妙なのは、クエリに時間がかかる場合があることです。たとえば、更新ボタンを 7 回続けて押すと、グリッドは 1 秒以内に更新されます。その後、8 回目の試行では 12 秒かかります。その後、Refresh をさらに 11 回押すと、再びすばやく実行されますが、12 回目には、再び 12 秒かかります。このようにかなり一貫しています。遅延があるたびに常に12秒かかるようです。それは何ですか?
クエリは次のとおりです。
IQueryable<EntityBase> installationSummaries =
QueryAndSetEtags(session => session.Query<InstallationSummary>()
.Include(x => x.ApplicationServerId)
.Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId)
.Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)
.Customize(x => x.WaitForNonStaleResults())
.OrderByDescending(summary => summary.InstallationStartUtc)
.Take(numberToRetrieve)
);
HydrateInstallationSummaries(installationSummaries);
return installationSummaries.AsEnumerable().Cast<InstallationSummary>();
遅延は常にこのコード行にあります (entityBases は上記のクエリからの戻り値です)。
List<EntityBase> entityBaseList = entityBases.ToList();
RavenDB でこのような問題をトラブルシューティングする正しい方法は何ですか? 次に何を試せばよいかわかりません。
注: このコードは長い間変更されていません。現在、RavenDB 960 を使用しています。これは RavenDB 573 では発生しませんでした。
編集 - このクエリの周りで他に何が起こっているかを示す追加のコード。
private static void HydrateInstallationSummaries(IQueryable<EntityBase> installationSummaries)
{
// Note: We use session.Load() below so that we get the information from the session, and not another trip to the DB.
foreach (InstallationSummary summary in installationSummaries)
{
HydrateInstallationSummary(summary);
}
}
private static void HydrateInstallationSummary(InstallationSummary summary)
{
if (summary == null) { return; }
summary.ApplicationServer =
QuerySingleResultAndSetEtag(session => session.Load<ApplicationServer>(summary.ApplicationServerId))
as ApplicationServer;
summary.ApplicationWithOverrideVariableGroup.Application =
QuerySingleResultAndSetEtag(session => session.Load<Application>(summary.ApplicationWithOverrideVariableGroup.ApplicationId))
as Application;
if (summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupId == null) { return; }
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroup =
QuerySingleResultAndSetEtag(session =>
{
if (session.Advanced.IsLoaded(summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupId))
{
return session.Load<CustomVariableGroup>(summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupId);
}
return null; // Note: We can be missing a custom variable in the session because someone deleted it.
;
})
as CustomVariableGroup;
}
そして、ここに QueryAndSetEtags() があります:
protected static IQueryable<EntityBase> QueryAndSetEtags(Func<IDocumentSession, IQueryable<EntityBase>> func)
{
if (func == null) { throw new ArgumentNullException("func"); }
IQueryable<EntityBase> entities = func.Invoke(_session);
SetEtags(entities, _session);
return entities;
}
protected static void SetEtags(IEnumerable<EntityBase> entityBases, IDocumentSession session)
{
foreach (EntityBase entityBase in entityBases)
{
SetEtag(entityBase, session);
}
}
protected static void SetEtag(EntityBase entityBase, IDocumentSession session)
{
entityBase.Etag = (Guid)session.Advanced.GetEtagFor(entityBase);
}