Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SQL performance option #4785

Merged
merged 6 commits into from
Jan 24, 2025
Merged

Add SQL performance option #4785

merged 6 commits into from
Jan 24, 2025

Conversation

LTA-Thinking
Copy link
Collaborator

@LTA-Thinking LTA-Thinking commented Jan 17, 2025

Description

Adds support for the x-ms-query-cache header for Gen2. This gives the user the option to control if SQL uses query caching on the request level. This can enable, disable, or have SQL run both and use the better performing one. This helps in situations where a user has some queries that perform better with query caching and some that perform better without it.

Related issues

Addresses User Story 137387: DDMS: SQL search with and without cache

Testing

Describe how this change was tested.

FHIR Team Checklist

  • Update the title of the PR to be succinct and less than 65 characters
  • Add a milestone to the PR for the sprint that it is merged (i.e. add S47)
  • Tag the PR with the type of update: Bug, Build, Dependencies, Enhancement, New-Feature or Documentation
  • Tag the PR with Open source, Azure API for FHIR (CosmosDB or common code) or Azure Healthcare APIs (SQL or common code) to specify where this change is intended to be released.
  • Tag the PR with Schema Version backward compatible or Schema Version backward incompatible or Schema Version unchanged if this adds or updates Sql script which is/is not backward compatible with the code.
  • CI is green before merge Build Status
  • Review squash-merge requirements

Semver Change (docs)

Patch

@LTA-Thinking LTA-Thinking added Enhancement Enhancement on existing functionality. Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs labels Jan 17, 2025
@LTA-Thinking LTA-Thinking added this to the 2Wk07 milestone Jan 17, 2025
@LTA-Thinking LTA-Thinking requested a review from a team as a code owner January 17, 2025 17:38
}

if (inputResource is not Parameters)
{
throw new RequestNotValidException(string.Format(Resources.UnsupportedResourceType, inputResource.GetType().ToString()));
throw new RequestNotValidException(string.Format(Api.Resources.UnsupportedResourceType, inputResource.GetType().ToString()));

Check notice

Code scanning / CodeQL

Redundant ToString() call Note

Redundant call to 'ToString' on a String object.
Comment on lines 234 to 258
if (string.Equals(useQueryCache, "true", StringComparison.OrdinalIgnoreCase))
{
return await SearchImpl(sqlSearchOptions, true, cancellationToken);
}
else if (string.Equals(useQueryCache, "false", StringComparison.OrdinalIgnoreCase))
{
return await SearchImpl(sqlSearchOptions, false, cancellationToken);
}
else if (string.Equals(useQueryCache, "both", StringComparison.OrdinalIgnoreCase))
{
_logger.LogInformation("Running search with and without query cache.");
var stopwatch = Stopwatch.StartNew();

using var tokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
var token = tokenSource.Token;

var tryWithQueryCache = SearchImpl(sqlSearchOptions, true, token);
var tryWithoutQueryCache = SearchImpl(sqlSearchOptions, false, token);

var result = await Task.WhenAny(tryWithQueryCache, tryWithoutQueryCache);
await tokenSource.CancelAsync();

_logger.LogInformation("First search completed in {ElapsedMilliseconds}ms, query cache enabled: {QueryCacheEnabled}.", stopwatch.ElapsedMilliseconds, result == tryWithQueryCache);
return await result;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to expose this on such a granular level?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see a way to let the user control this setting with less visibility.
I know we try and keep the database operations opaque to the user, but since we've seen this setting can dramatically affect query performance I think it would be a good lever to be able to pull if needed. 

{
return await SearchImpl(sqlSearchOptions, false, cancellationToken);
}
else if (string.Equals(useQueryCache, "both", StringComparison.OrdinalIgnoreCase))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be an enum?

@brendankowitz
Copy link
Member

I think the description is now out of date for "x-ms-query-latency-over-efficiency"

{
internal class QueryCacheSetting
{
public const string Enabled = "enabled";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Maybe an enumeration

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C# doesn't support string enumerations. Since this is mapping from a user inputted header value this is the best I could think of.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true you would need something like: Enum.TryParse(x, out QueryCacheSettingsEnum cacheSetting);

But more of a suggestion.

&& useQueryCacheObj != null)
{
var useQueryCache = Convert.ToString(useQueryCacheObj);
if (string.Equals(useQueryCache, QueryCacheSetting.Enabled, StringComparison.OrdinalIgnoreCase))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: perhaps reading the value once and convert to enum instead of multiple string comparisions

@@ -357,7 +402,7 @@ await _sqlRetryService.ExecuteSql(
new HashingSqlQueryParameterManager(new SqlQueryParameterManager(sqlCommand.Parameters)),
_model,
_schemaInformation,
_reuseQueryPlans.IsEnabled(_sqlRetryService),
reuseQueryPlans,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows the setting to use or not use query plans to be controlled from an input parameter, which is then controlled by the header value parsing code.

@LTA-Thinking LTA-Thinking merged commit 39b1898 into main Jan 24, 2025
49 checks passed
@LTA-Thinking LTA-Thinking deleted the personal/rojo/sql-perf-option branch January 24, 2025 22:53
LTA-Thinking added a commit that referenced this pull request Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs Enhancement Enhancement on existing functionality.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants