[Internal] Query: Adds performance testing for OptimisticDirectExecution pipeline (#3839)

* Infrastructure for performance testing with ODE pipeline.

* Resolve comments

* Removed randomization from data creation process

* Fixed comments

* Removed Query and EnableODE from QueryStatisticsMetrics, as they do not relate to query statistics.

* Removed try catch to make CreateItemAsync call always succeed

* Removed one liner functions

* Removed code from MetricsSerializer and QueryStatisticsDatumVisitor files

* Fixed comments

* Removed request Charge check

* Bug in Debug Assert

* Test

* Bug in debug assert fix

* Fixed second bug in Metrics Accumalator class

* Added ignore flag to ode perf tests so that they do not run on every loop build

* Added comment explaining the Ignore flag.
This commit is contained in:
akotalwar 2023-08-05 13:01:59 -07:00 коммит произвёл GitHub
Родитель ebd1b91a26
Коммит 8c4f99f35e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 496 добавлений и 23 удалений

Просмотреть файл

@ -33,15 +33,15 @@
this.queryStatisticsDatumVisitor = new();
this.endpoint = Utils.ConfigurationManager.AppSettings["GatewayEndpoint"];
this.authKey = Utils.ConfigurationManager.AppSettings["MasterKey"];
this.cosmosDatabaseId = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.CosmosDatabaseId"];
this.containerId = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.ContainerId"];
this.contentSerialization = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.ContentSerialization"];
this.query = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.Query"];
this.numberOfIterations = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.NumberOfIterations"]);
this.warmupIterations = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.WarmupIterations"]);
this.MaxConcurrency = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.MaxConcurrency"]);
this.MaxItemCount = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.MaxItemCount"]);
this.useStronglyTypedIterator = bool.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.UseStronglyTypedIterator"]);
this.cosmosDatabaseId = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.CosmosDatabaseId"];
this.containerId = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.ContainerId"];
this.contentSerialization = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.ContentSerialization"];
this.query = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.Query"];
this.numberOfIterations = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.NumberOfIterations"]);
this.warmupIterations = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.WarmupIterations"]);
this.MaxConcurrency = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.MaxConcurrency"]);
this.MaxItemCount = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.MaxItemCount"]);
this.useStronglyTypedIterator = bool.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.UseStronglyTypedIterator"]);
}
[TestMethod]

Просмотреть файл

@ -53,18 +53,16 @@
{
if (storeResponse.StoreResult.StatusCode == StatusCodes.Ok)
{
backendAndClientMetrics.Add(Tuple.Create(retrieveCosmosElementTraces[k], backendMetrics[j], transitMetrics[i]));
backendAndClientMetrics.Add(Tuple.Create(retrieveCosmosElementTraces[k], backendMetrics[j], node));
j++;
k++;
}
else
{
//We add null values to the tuple since status codes other than Ok will not have data for 'Query Metrics' and 'Get Cosmos Element Response'
backendAndClientMetrics.Add(Tuple.Create<ITrace, ITrace, ITrace>(null, null, transitMetrics[i]));
backendAndClientMetrics.Add(Tuple.Create<ITrace, ITrace, ITrace>(null, null, node));
}
}
i++;
}
Debug.Assert(i == transitMetrics.Count, "All 'transit metrics' must be grouped.");
@ -76,7 +74,7 @@
{
if (metrics.Item2 != null)
{
Debug.Assert(metrics.Item1 == null, "'Get Cosmos Element Response' is null");
Debug.Assert(metrics.Item1 != null, "'Get Cosmos Element Response' is null");
queryStatisticsDatumVisitor.AddGetCosmosElementResponseTime(metrics.Item1.Duration.TotalMilliseconds);
foreach (KeyValuePair<string, object> kvp in metrics.Item2.Data)
{

Просмотреть файл

@ -0,0 +1,469 @@
namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class OptimisticDirectExecutionPerformanceTests
{
private Container Container;
private const string RawDataFileName = "OptimisticDirectExecutionPerformanceTestsRawData.csv";
private const string AggregateDataFileName = "OptimisticDirectExecutionPerformanceTestsAggregatedData.csv";
private const string PrintQueryMetrics = "QueryMetrics";
private static readonly string RawDataPath = Path.GetFullPath(RawDataFileName);
private static readonly string AggregateDataPath = Path.GetFullPath(AggregateDataFileName);
private static readonly string Endpoint = Utils.ConfigurationManager.AppSettings["GatewayEndpoint"];
private static readonly string AuthKey = Utils.ConfigurationManager.AppSettings["MasterKey"];
private static readonly string CosmosDatabaseId = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.CosmosDatabaseId"];
private static readonly string ContainerId = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.ContainerId"];
private static readonly PartitionKey PartitionKeyValue = new PartitionKey("Andersen");
private static readonly int NumberOfIterations = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.NumberOfIterations"]);
private static readonly int WarmupIterations = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.WarmupIterations"]);
[TestInitialize]
public async Task InitializeTest()
{
CosmosClientOptions clientOptions = new CosmosClientOptions()
{
ConnectionMode = ConnectionMode.Direct,
};
CosmosClient cosmosClient = new CosmosClient(Endpoint, AuthKey, clientOptions);
Database database = await cosmosClient.CreateDatabaseAsync(CosmosDatabaseId);
this.Container = await database.CreateContainerAsync(ContainerId, partitionKeyPath: "/name");
await this.AddItemsToContainerAsync(this.Container);
if (File.Exists(RawDataPath))
{
File.Delete(RawDataPath);
}
if (File.Exists(AggregateDataPath))
{
File.Delete(AggregateDataPath);
}
}
[TestCleanup]
public async Task CleanupAsync()
{
if (this.Container != null)
{
await this.Container.Database.DeleteAsync();
this.Container = null;
}
}
private async Task AddItemsToContainerAsync(Container container)
{
int totalItems = 5000;
string[] cityOptions = new string[] { "Seattle", "Chicago", "NYC", "SF" };
int numberOfRecipeints = cityOptions.Length;
List<RecipientList> recipientList = new List<RecipientList>(numberOfRecipeints);
for (int j = 0; j < numberOfRecipeints; j++)
{
RecipientList recipient = new RecipientList()
{
Name = "John",
City = cityOptions[j],
};
recipientList.Add(recipient);
}
// Create a family object for the Andersen family
foreach (int i in Enumerable.Range(0, totalItems))
{
States andersenFamily = new States
{
Id = i.ToString(),
Name = i < (totalItems/2) ? "Andersen" : "Smith",
City = cityOptions[i%cityOptions.Length],
PostalCode = (i * 10).ToString(),
Region = "Northwest",
UserDefinedID = i % 10,
RecipientList = recipientList
};
ItemResponse<States> andersenFamilyResponse = await container.CreateItemAsync<States>(andersenFamily, new PartitionKey(andersenFamily.Name));
Console.WriteLine("Created item in database with id: {0} Operation consumed {1} RUs.\n", andersenFamilyResponse.Resource.Id, andersenFamilyResponse.RequestCharge);
}
}
//Set Ode perf tests to ignore so that they dont run on every loop build.
//Ignore flag can be removed when checking for Ode performance.
[Ignore]
[TestMethod]
[Owner("akotalwar")]
public async Task RunAsync()
{
string highPrepTimeSumQuery = CreateHighPrepTimeSumQuery();
string highPrepTimeConditionalQuery = CreateHighPrepTimeConditionalQuery();
List<List<OdeQueryStatistics>> globalCustomOdeStatisticsList = new List<List<OdeQueryStatistics>>();
List<DirectExecutionTestCase> odeTestCases = new List<DirectExecutionTestCase>()
{
//Simple Query
CreateInput("SELECT * FROM c", PartitionKeyValue, false, -1, 2500),
CreateInput("SELECT * FROM c", PartitionKeyValue, true, -1, 2500),
//TOP
CreateInput("SELECT TOP 1000 c.id FROM c", PartitionKeyValue, false, -1, 1000),
CreateInput("SELECT TOP 1000 c.id FROM c", PartitionKeyValue, true, -1, 1000),
//Filter
CreateInput("SELECT c.id FROM c WHERE c.city IN ('Seattle', 'NYC')", PartitionKeyValue, false, -1, 1250),
CreateInput("SELECT c.id FROM c WHERE c.city IN ('Seattle', 'NYC')", PartitionKeyValue, true, -1, 1250),
//DISTINCT + Filter
CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId BETWEEN 0 AND 5 OFFSET 1 LIMIT 3", PartitionKeyValue, false, -1, 3),
CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId BETWEEN 0 AND 5 OFFSET 1 LIMIT 3", PartitionKeyValue, true, -1, 3),
CreateInput("SELECT DISTINCT c.city FROM c WHERE STARTSWITH(c.city, 'S')", PartitionKeyValue, false, -1, 2),
CreateInput("SELECT DISTINCT c.city FROM c WHERE STARTSWITH(c.city, 'S')", PartitionKeyValue, true, -1, 2),
//JOIN
CreateInput("SELECT root.id " +
"FROM root " +
"JOIN root.id a " +
"JOIN root.id b " +
"JOIN root.id c " +
"WHERE root.id = '1' OR a.id in (1,2,3,4,5,6,7,8,9,10) " +
"OR b.id in (1,2,3,4,5,6,7,8,9,10) " +
"OR c.id in (1,2,3,4,5,6,7,8,9,10)", PartitionKeyValue, false, -1, 1),
CreateInput("SELECT root.id " +
"FROM root " +
"JOIN root.id a " +
"JOIN root.id b " +
"JOIN root.id c " +
"WHERE root.id = '1' OR a.id in (1,2,3,4,5,6,7,8,9,10) " +
"OR b.id in (1,2,3,4,5,6,7,8,9,10) " +
"OR c.id in (1,2,3,4,5,6,7,8,9,10)", PartitionKeyValue, true, -1, 1),
//High Prep Time
CreateInput(highPrepTimeSumQuery, PartitionKeyValue, false, -1, 2500),
CreateInput(highPrepTimeSumQuery, PartitionKeyValue, true, -1, 2500),
CreateInput(highPrepTimeConditionalQuery, PartitionKeyValue, false, -1, 1750),
CreateInput(highPrepTimeConditionalQuery, PartitionKeyValue, true, -1, 1750),
//Order By
CreateInput("SELECT * FROM c ORDER BY c.userDefinedId DESC", PartitionKeyValue, false, -1, 2500),
CreateInput("SELECT * FROM c ORDER BY c.userDefinedId DESC", PartitionKeyValue, true, -1, 2500),
CreateInput("SELECT c.id FROM c ORDER BY c.postalcode DESC", PartitionKeyValue, false, -1, 2500),
CreateInput("SELECT c.id FROM c ORDER BY c.postalcode DESC", PartitionKeyValue, true, -1, 2500),
//Order By + TOP
CreateInput("SELECT TOP 5 c.id FROM c ORDER BY c.userDefinedId", PartitionKeyValue, false, -1, 5),
CreateInput("SELECT TOP 5 c.id FROM c ORDER BY c.userDefinedId", PartitionKeyValue, true, -1, 5),
//Order By + DISTINCT
CreateInput("SELECT DISTINCT c.id FROM c ORDER BY c.city DESC", PartitionKeyValue, false, -1, 2500),
CreateInput("SELECT DISTINCT c.id FROM c ORDER BY c.city DESC", PartitionKeyValue, true, -1, 2500),
//Order By + DISTINCT + Filter
CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId > 5 ORDER BY c.userDefinedId", PartitionKeyValue, false, -1, 4),
CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId > 5 ORDER BY c.userDefinedId", PartitionKeyValue, true, -1, 4),
CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId BETWEEN 0 AND 5 ORDER BY c.id DESC", PartitionKeyValue, false, -1, 6),
CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId BETWEEN 0 AND 5 ORDER BY c.id DESC", PartitionKeyValue, true, -1, 6),
//Group By
CreateInput("SELECT c.postalcode FROM c GROUP BY c.postalcode", PartitionKeyValue, false, -1, 2500),
CreateInput("SELECT c.postalcode FROM c GROUP BY c.postalcode", PartitionKeyValue, true, -1, 2500),
CreateInput("SELECT Count(1) AS count, Sum(ARRAY_LENGTH(c.recipientList)) AS sum FROM c WHERE c.city IN ('Seattle', 'SF') GROUP BY c.city", PartitionKeyValue, false, -1, 2),
CreateInput("SELECT Count(1) AS count, Sum(ARRAY_LENGTH(c.recipientList)) AS sum FROM c WHERE c.city IN ('Seattle', 'SF') GROUP BY c.city", PartitionKeyValue, true, -1, 2),
CreateInput("SELECT c.city, AVG(ARRAY_LENGTH(c.recipientList)) FROM c GROUP BY c.city", PartitionKeyValue, false, -1, 4),
CreateInput("SELECT c.city, AVG(ARRAY_LENGTH(c.recipientList)) FROM c GROUP BY c.city", PartitionKeyValue, true, -1, 4),
//Group By + OFFSET
CreateInput("SELECT c.id FROM c GROUP BY c.id OFFSET 5 LIMIT 3", PartitionKeyValue, false, -1, 3),
CreateInput("SELECT c.id FROM c GROUP BY c.id OFFSET 5 LIMIT 3", PartitionKeyValue, true, -1, 3),
//Group By + TOP
CreateInput("SELECT TOP 25 c.id FROM c GROUP BY c.id", PartitionKeyValue, false, -1, 25),
CreateInput("SELECT TOP 25 c.id FROM c GROUP BY c.id", PartitionKeyValue, true, -1, 25),
//Group By + DISTINCT
CreateInput("SELECT DISTINCT c.id FROM c GROUP BY c.id", PartitionKeyValue, false, -1, 2500),
CreateInput("SELECT DISTINCT c.id FROM c GROUP BY c.id", PartitionKeyValue, true, -1, 2500),
CreateInput("SELECT DISTINCT c.postalcode FROM c GROUP BY c.postalcode", PartitionKeyValue, false, -1, 2500),
CreateInput("SELECT DISTINCT c.postalcode FROM c GROUP BY c.postalcode", PartitionKeyValue, true, -1, 2500),
};
foreach (DirectExecutionTestCase testCase in odeTestCases)
{
globalCustomOdeStatisticsList.AddRange(await this.RunQueryAsync(testCase));
}
using (StreamWriter writer = new StreamWriter(new FileStream(RawDataPath, FileMode.Append, FileAccess.Write)))
{
SerializeODEQueryMetrics(writer, globalCustomOdeStatisticsList, NumberOfIterations, rawData: true);
}
using (StreamWriter writer = new StreamWriter(new FileStream(AggregateDataPath, FileMode.Append, FileAccess.Write)))
{
SerializeODEQueryMetrics(writer, globalCustomOdeStatisticsList, NumberOfIterations, rawData: false);
}
}
private async Task<List<List<OdeQueryStatistics>>> RunQueryAsync(DirectExecutionTestCase queryInput)
{
List<List<OdeQueryStatistics>> odeQueryStatisticsList = new List<List<OdeQueryStatistics>>();
QueryRequestOptions requestOptions = new QueryRequestOptions()
{
MaxItemCount = queryInput.PageSizeOption,
EnableOptimisticDirectExecution = queryInput.EnableOptimisticDirectExecution,
PartitionKey = queryInput.PartitionKey,
};
for (int i = 0; i < NumberOfIterations + WarmupIterations; i++)
{
bool isWarmUpIteration = i < WarmupIterations;
using (FeedIterator<States> iterator = this.Container.GetItemQueryIterator<States>(
queryText: queryInput.Query,
requestOptions: requestOptions))
{
if (isWarmUpIteration)
{
while (iterator.HasMoreResults)
{
await iterator.ReadNextAsync();
}
}
else
{
odeQueryStatisticsList.Add(await this.GetIteratorStatistics(iterator, queryInput));
}
}
}
return odeQueryStatisticsList;
}
private async Task<List<OdeQueryStatistics>> GetIteratorStatistics<T>(FeedIterator<T> feedIterator, DirectExecutionTestCase queryInput)
{
MetricsAccumulator metricsAccumulator = new MetricsAccumulator();
Guid correlatedActivityId = Guid.NewGuid();
FeedResponse<T> response;
int totalDocumentCount = 0;
string query;
bool enableOde;
List<OdeQueryStatistics> odeQueryStatisticsList = new List<OdeQueryStatistics>();
while (feedIterator.HasMoreResults)
{
QueryStatisticsDatumVisitor queryStatisticsDatumVisitor = new QueryStatisticsDatumVisitor();
System.Diagnostics.Stopwatch totalTime = new System.Diagnostics.Stopwatch();
System.Diagnostics.Stopwatch traceTime = new System.Diagnostics.Stopwatch();
totalTime.Start();
response = await feedIterator.ReadNextAsync();
traceTime.Start();
if (response.RequestCharge != 0)
{
metricsAccumulator.ReadFromTrace(response, queryStatisticsDatumVisitor);
}
traceTime.Stop();
totalTime.Stop();
query = queryInput.Query;
enableOde = queryInput.EnableOptimisticDirectExecution;
queryStatisticsDatumVisitor.AddEndToEndTime(totalTime.ElapsedMilliseconds - traceTime.ElapsedMilliseconds);
queryStatisticsDatumVisitor.PopulateMetrics();
QueryStatisticsMetrics queryStatistics = queryStatisticsDatumVisitor.QueryMetricsList[0];
queryStatistics.RUCharge = response.RequestCharge;
queryStatistics.CorrelatedActivityId = correlatedActivityId;
// Each roundtrip is a new item in the list
odeQueryStatisticsList.Add(new OdeQueryStatistics
{
Query = query,
EnableOde = enableOde,
QueryStatisticsMetrics = queryStatistics
});
totalDocumentCount += response.Count;
}
Assert.AreEqual(queryInput.ExpectedResultCount, totalDocumentCount);
return odeQueryStatisticsList;
}
private static string CreateHighPrepTimeSumQuery()
{
int exprCount = 9999;
StringBuilder sb = new StringBuilder();
sb.Append("SELECT r.id FROM root r WHERE ");
for (int i = 0; i < exprCount; i++)
{
sb.Append(i == 0 ? "1" : "+1");
}
return sb.Append(" = " + exprCount + " ORDER BY r.id ASC").ToString();
}
private static string CreateHighPrepTimeConditionalQuery()
{
int exprCount = 999;
StringBuilder sb = new StringBuilder();
string[] cityOptions = new string[] { "Seattle", "Chicago", "NYC", "SF" };
sb.Append("SELECT * FROM root r WHERE ");
for (int nIdx = 0; nIdx < exprCount; nIdx++)
{
if (nIdx > 0)
{
sb.Append(" OR ");
}
sb.Append($"r.userDefinedId > {nIdx} AND r.city = '{cityOptions[nIdx % cityOptions.Length]}'");
}
return sb.ToString();
}
private static void SerializeODEQueryMetrics(TextWriter textWriter, List<List<OdeQueryStatistics>> customOdeStatisticsList, int numberOfIterations, bool rawData)
{
if (rawData)
{
SerializeODERawDataQueryMetrics(textWriter, customOdeStatisticsList);
}
else
{
SerializeODEProcessedDataQueryMetrics(textWriter, customOdeStatisticsList, numberOfIterations);
}
}
private static void SerializeODERawDataQueryMetrics(TextWriter textWriter, List<List<OdeQueryStatistics>> globalOdeQueryStatisticsList)
{
textWriter.WriteLine();
textWriter.WriteLine(PrintQueryMetrics);
textWriter.Write("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\"", "Query", "ODE", "RUCharge", "BackendTime", "TransitTime", "ClientTime", "EndToEndTime");
textWriter.WriteLine();
foreach (List<OdeQueryStatistics> queryStatisticsList in globalOdeQueryStatisticsList)
{
double totalClientTime = 0;
double totalBackendTime = 0;
double totalEndToEndTime = 0;
double totalTransitTime = 0;
double totalRU = 0;
string query = "";
bool ode = false;
foreach (OdeQueryStatistics queryStatistics in queryStatisticsList)
{
QueryStatisticsMetrics metrics = queryStatistics.QueryStatisticsMetrics;
double transitTime = metrics.Created + metrics.ChannelAcquisitionStarted + metrics.Pipelined + metrics.Received + metrics.Completed;
double backendTime = metrics.TotalQueryExecutionTime;
totalClientTime += metrics.EndToEndTime - (backendTime + transitTime);
totalBackendTime += backendTime;
totalEndToEndTime += metrics.EndToEndTime;
totalTransitTime += transitTime;
totalRU += metrics.RUCharge;
query = queryStatistics.Query;
ode = queryStatistics.EnableOde;
}
textWriter.WriteLine($"{query},{ode},{totalRU},{totalBackendTime},{totalTransitTime},{totalClientTime},{totalEndToEndTime}");
}
}
private static void SerializeODEProcessedDataQueryMetrics(TextWriter textWriter, List<List<OdeQueryStatistics>> globalOdeQueryStatisticsList, int numberOfIterations)
{
textWriter.WriteLine();
textWriter.WriteLine(PrintQueryMetrics);
textWriter.Write("\"{0}\",\"{1}\",\"{2}\",\"{3}\"", "Query", "ODE", "RUCharge", "EndToEndTime");
textWriter.WriteLine();
string prevQuery = globalOdeQueryStatisticsList[0][0].Query;
bool prevOde = globalOdeQueryStatisticsList[0][0].EnableOde;
double totalEndToEndTime = 0;
double totalRU = 0;
foreach (List<OdeQueryStatistics> odeQueryStatisticsList in globalOdeQueryStatisticsList)
{
if (odeQueryStatisticsList[0].Query == prevQuery && odeQueryStatisticsList[0].EnableOde == prevOde)
{
foreach (OdeQueryStatistics odeQueryStatistics in odeQueryStatisticsList)
{
QueryStatisticsMetrics metrics = odeQueryStatistics.QueryStatisticsMetrics;
totalEndToEndTime += metrics.EndToEndTime;
totalRU += metrics.RUCharge;
}
}
else
{
textWriter.WriteLine($"{prevQuery},{prevOde},{totalRU / numberOfIterations},{totalEndToEndTime / numberOfIterations}");
foreach (OdeQueryStatistics odeQueryStatistics in odeQueryStatisticsList)
{
QueryStatisticsMetrics metrics = odeQueryStatistics.QueryStatisticsMetrics;
totalEndToEndTime = metrics.EndToEndTime;
totalRU = metrics.RUCharge;
prevQuery = odeQueryStatistics.Query;
prevOde = odeQueryStatistics.EnableOde;
}
}
}
textWriter.WriteLine($"{prevQuery},{prevOde},{totalRU / numberOfIterations},{totalEndToEndTime / numberOfIterations}");
}
private class OdeQueryStatistics
{
public string Query { get; set; }
public bool EnableOde { get; set; }
public QueryStatisticsMetrics QueryStatisticsMetrics { get; set; }
}
private static DirectExecutionTestCase CreateInput(
string query,
PartitionKey? partitionKey,
bool enableOptimisticDirectExecution,
int pageSizeOption,
int expectedResultCount)
{
return new DirectExecutionTestCase(query, partitionKey, enableOptimisticDirectExecution, pageSizeOption, expectedResultCount);
}
private readonly struct DirectExecutionTestCase
{
public string Query { get; }
public PartitionKey? PartitionKey { get; }
public bool EnableOptimisticDirectExecution { get; }
public int PageSizeOption { get; }
public int ExpectedResultCount { get; }
public DirectExecutionTestCase(
string query,
PartitionKey? partitionKey,
bool enableOptimisticDirectExecution,
int pageSizeOption,
int expectedResultCount)
{
this.Query = query;
this.PartitionKey = partitionKey;
this.EnableOptimisticDirectExecution = enableOptimisticDirectExecution;
this.PageSizeOption = pageSizeOption;
this.ExpectedResultCount = expectedResultCount;
}
}
}
}

Просмотреть файл

@ -1,7 +1,11 @@
namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
{
using System;
internal class QueryStatisticsMetrics
{
public Guid CorrelatedActivityId { get; set; }
public double EndToEndTime { get; set; }
public double PocoTime { get; set; }
@ -32,6 +36,8 @@
public double Received { get; set; }
public double RUCharge { get; set; }
public double Completed { get; set; }
public double BadRequestCreated { get; set; }

Просмотреть файл

@ -11,14 +11,14 @@
"MasterKey": "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
"ServerStalenessIntervalInSeconds": "5",
"MasterStalenessIntervalInSeconds": "1",
"ContentSerializationPerformanceTests.CosmosDatabaseId": "db",
"ContentSerializationPerformanceTests.ContainerId": "container",
"ContentSerializationPerformanceTests.ContentSerialization": "JsonText",
"ContentSerializationPerformanceTests.Query": "SELECT TOP 1 c.region FROM c",
"ContentSerializationPerformanceTests.MaxConcurrency": "-1",
"ContentSerializationPerformanceTests.MaxItemCount": "-1",
"ContentSerializationPerformanceTests.NumberOfIterations": "1",
"ContentSerializationPerformanceTests.WarmupIterations": "0",
"ContentSerializationPerformanceTests.UseStronglyTypedIterator": "true"
"QueryPerformanceTests.CosmosDatabaseId": "db",
"QueryPerformanceTests.ContainerId": "container",
"QueryPerformanceTests.ContentSerialization": "JsonText",
"QueryPerformanceTests.Query": "SELECT TOP 1 c.region FROM c",
"QueryPerformanceTests.MaxConcurrency": "-1",
"QueryPerformanceTests.MaxItemCount": "-1",
"QueryPerformanceTests.NumberOfIterations": "1",
"QueryPerformanceTests.WarmupIterations": "0",
"QueryPerformanceTests.UseStronglyTypedIterator": "true"
}
}