Skip to content

[sqlserver] Share one performance counter query and index rows by instance - #24908

Open
eric-weaver wants to merge 5 commits into
masterfrom
eric.weaver/sqlserver-perf-counter-shared-query
Open

[sqlserver] Share one performance counter query and index rows by instance#24908
eric-weaver wants to merge 5 commits into
masterfrom
eric.weaver/sqlserver-perf-counter-shared-query

Conversation

@eric-weaver

Copy link
Copy Markdown
Contributor

What does this PR do?

The three metric classes that read sys.dm_os_performance_counters now share one query and one snapshot of the table, and the rows are indexed by instance name as well as counter name so each metric looks its rows up instead of scanning for them.

A fraction metric whose base counter is missing for its instance is now skipped rather than raising, which previously abandoned the remaining metrics for that run.

Motivation

Follow-up to #24876. Scanning that table costs about the same whether it returns two rows or thousands, so a query per metric class is overhead: at 1000 autodiscovered databases the two fraction queries spent 110ms between them to return four rows each. Grouping by counter name alone also left the dispatch quadratic, because every per-database metric still walked its counter's rows looking for its own instance; indexing by instance takes that from 234ms to 3ms.

At 1000 autodiscovered databases with DBM enabled, the steady-state run drops from 2938ms to 2423ms (medians of six runs on the same instance).

Emitted data is unchanged: at 100 databases, with an instance_name: ALL custom metric configured, an agent check --json capture emits an identical set of 5797 (metric, type, tag set) series.

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Add qa/required if this PR needs QA validation, or qa/skip-qa if it does not. Exactly one of the two is required.
  • If you need to backport this PR to another branch, you can add the backport/<branch-name> label to the PR and it will automatically open a backport PR once this one is merged

…tance

The three metric classes that read sys.dm_os_performance_counters each issued their own query, and
scanning that table costs about the same whether it returns two rows or thousands: at 1000
autodiscovered databases the two fraction queries spent 110ms between them to return four rows. They
now share a single fetch over the union of their counter names.

Grouping rows by counter name left the dispatch quadratic, because every per-database metric still
scanned the rows of its own counter looking for its instance. Indexing by instance name as well turns
that scan into a lookup, which takes the dispatch from 234ms to 3ms at 1000 databases.

Together these cut the steady-state check from 2938ms to 2423ms at 1000 databases, measured on the
same instance, and the emitted series and tag sets are unchanged.

A fraction metric whose base counter is missing for its instance is now skipped rather than raising,
which previously abandoned the remaining metrics for that run.

Co-authored-by: Cursor <cursoragent@cursor.com>
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Aug 18, 2026

Copy link
Copy Markdown

Tests  Code Coverage

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 92.59%
Overall Coverage: 90.82% (+2.23%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 8b800c9 | Docs | View more details | Give us feedback!

Co-authored-by: Cursor <cursoragent@cursor.com>
@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 18, 2026

Copy link
Copy Markdown

evalya-impact-summary

evalya impact analysis
Impact analysis: 0 selected, 0 skipped (of 0 test tasks)
Publish tasks:   1 (always emitted)
Diff (5 files):
  sqlserver/changelog.d/24908.fixed
  sqlserver/datadog_checks/sqlserver/metrics.py
  sqlserver/datadog_checks/sqlserver/sqlserver.py
  sqlserver/tests/common.py
  sqlserver/tests/test_unit.py

Debug a specific task: evalya plan impact --path <path> --task <task>

Learn more about CI impact filtering

The tag depends only on the instance name, so constructing it in the row loop put it a level below
where it belongs. The rows of one counter and instance are almost always a single row, so this is for
the reader rather than for speed.

Co-authored-by: Cursor <cursoragent@cursor.com>
@eric-weaver eric-weaver added the qa/skip-qa Automatically skip this PR for the next QA label Aug 18, 2026
…sertions

The three tracked operations became one, so the integration tests asserting a
dd.sqlserver.operation.time series per operation name were looking for tags no longer emitted.

Co-authored-by: Cursor <cursoragent@cursor.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f5fac9d1a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread sqlserver/datadog_checks/sqlserver/metrics.py Outdated
Names the nested index the dispatch reads from, so the shape is stated once rather than inferred from
the loops that walk it.

Co-authored-by: Cursor <cursoragent@cursor.com>
@dd-octo-sts

dd-octo-sts Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Validation Report

All 21 validations passed.

Show details
Validation Description Status
agent-reqs Verify check versions match the Agent requirements file
ci Validate CI configuration and code coverage settings
codeowners Validate every integration has a CODEOWNERS entry
config Validate default configuration files against spec.yaml
dep Verify dependency pins are consistent and Agent-compatible
http Validate integrations use the HTTP wrapper correctly
imports Validate check imports do not use deprecated modules
integration-style Validate check code style conventions
jmx-metrics Validate JMX metrics definition files and config
labeler Validate PR labeler config matches integration directories
legacy-signature Validate no integration uses the legacy Agent check signature
license-headers Validate Python files have proper license headers
licenses Validate third-party license attribution list
metadata Validate metadata.csv metric definitions
models Validate configuration data models match spec.yaml
openmetrics Validate OpenMetrics integrations disable the metric limit
package Validate Python package metadata and naming
qa-label Validate the pull request declares whether it needs QA for the next Agent release
readmes Validate README files have required sections
saved-views Validate saved view JSON file structure and fields
version Validate version consistency between package and changelog

View full run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant