Skip to content

Comments

Use lateral join with subquery on user_statistics table in account_view for network stats#12631

Open
sureshanaparti wants to merge 1 commit intoapache:4.22from
shapeblue:lateral-join-in-account_view-for-netstats
Open

Use lateral join with subquery on user_statistics table in account_view for network stats#12631
sureshanaparti wants to merge 1 commit intoapache:4.22from
shapeblue:lateral-join-in-account_view-for-netstats

Conversation

@sureshanaparti
Copy link
Contributor

@sureshanaparti sureshanaparti commented Feb 11, 2026

Description

This PR uses lateral join (introduced in MySQL 8.0.14) with subquery on user_statistics table in account_view for network stats.

There was a performance issue while querying account_view, which performs full table scans on the user_statistics table, resulting in execution time.

The original account_view used account_netstats_view which aggregates network statistics from the user_statistics table. MySQL's query optimizer could not push WHERE predicates through the nested view with GROUP BY, causing it to materialize the entire derived table before filtering. LATERAL JOIN (supported from MySQL 8.0.14+) allows correlated subqueries where the predicate can be applied before aggregation, avoiding materialization.

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

  • account_view updated with lateral join.

SHOW CREATE VIEW account_view;

  • account_netstats_view shouldn't exist, this should fail.

SHOW CREATE VIEW account_netstats_view;

  • account_view queries execute in less time than before (query performance improved).

SELECT * FROM account_view WHERE id = 3;

  • EXPLAIN shows ref access on user_statistics (not index scan)

EXPLAIN ANALYZE SELECT * FROM account_view WHERE id = 3 \G

How did you try to break this feature and the system with this change?

…tatistics table in account_view for netstats
@sureshanaparti
Copy link
Contributor Author

@blueorangutan package

@blueorangutan
Copy link

@sureshanaparti a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 17.62%. Comparing base (7324ef4) to head (c960fbf).

Additional details and impacted files
@@             Coverage Diff              @@
##               4.22   #12631      +/-   ##
============================================
- Coverage     17.62%   17.62%   -0.01%     
+ Complexity    15668    15665       -3     
============================================
  Files          5917     5917              
  Lines        531255   531255              
  Branches      64951    64951              
============================================
- Hits          93639    93616      -23     
- Misses       427077   427100      +23     
  Partials      10539    10539              
Flag Coverage Δ
uitests 3.70% <ø> (ø)
unittests 18.69% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sureshanaparti
Copy link
Contributor Author

sureshanaparti commented Feb 11, 2026

@DaanHoogland @nvazquez & Others - Should we update MySQL version to 8.0.14 in the compatibility matrix here: https://docs.cloudstack.apache.org/en/4.22.0.0/releasenotes/compat.html ?

@blueorangutan
Copy link

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 16799

@nvazquez
Copy link
Contributor

Thanks @sureshanaparti - actually the support for Mysql 8.4 is planned for 4.22.1 (#12417) as 8.0 is reaching EOL in April this year, so I think we can hold this PR until the 8.4 support is verified (and a doc PR won't be needed for 8.0.14 as the compatibility matrix will be updated to 8.4)

@DaanHoogland
Copy link
Contributor

Thanks @sureshanaparti - actually the support for Mysql 8.4 is planned for 4.22.1 (#12417) as 8.0 is reaching EOL in April this year, so I think we can hold this PR until the 8.4 support is verified (and a doc PR won't be needed for 8.0.14 as the compatibility matrix will be updated to 8.4)

in that case we need to update the 4.20 branch as well.

@sureshanaparti
Copy link
Contributor Author

@blueorangutan test

@blueorangutan
Copy link

@sureshanaparti a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan
Copy link

[SF] Trillian test result (tid-15450)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 53425 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr12631-t15450-kvm-ol8.zip
Smoke tests completed. 146 look OK, 3 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
ContextSuite context=TestListIdsParams>:teardown Error 1.12 test_list_ids_parameter.py
test_01_snapshot_root_disk Error 6.64 test_snapshots.py
test_02_list_snapshots_with_removed_data_store Error 55.38 test_snapshots.py
test_02_list_snapshots_with_removed_data_store Error 55.38 test_snapshots.py
ContextSuite context=TestSnapshotStandaloneBackup>:teardown Error 28.64 test_snapshots.py
test_01_snapshot_usage Error 23.67 test_usage.py
test_01_vpn_usage Error 1.33 test_usage.py

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes the account_view database view by replacing the separate account_netstats_view with a LATERAL JOIN directly in the main view. The change addresses a performance issue where the MySQL optimizer could not push WHERE predicates through the nested view with GROUP BY, causing full table scans on the user_statistics table. The LATERAL JOIN allows correlated subqueries where predicates can be applied before aggregation, enabling efficient use of the existing UNIQUE KEY on account_id in the user_statistics table.

Changes:

  • Replaced account_netstats_view reference with LATERAL JOIN subquery in account_view
  • Deleted the cloud.account_netstats_view.sql view definition file
  • Added DROP VIEW statement for account_netstats_view in cleanup migration script

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
engine/schema/src/main/resources/META-INF/db/views/cloud.account_view.sql Replaced left join with account_netstats_view with a LATERAL JOIN containing an inline subquery on user_statistics table
engine/schema/src/main/resources/META-INF/db/views/cloud.account_netstats_view.sql Deleted the view file as it's no longer needed
engine/schema/src/main/resources/META-INF/db/schema-42200to42210-cleanup.sql Added DROP VIEW statement to remove account_netstats_view during upgrade

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +92 to +100
left join lateral (
select
coalesce(sum(`user_statistics`.`net_bytes_received` + `user_statistics`.`current_bytes_received`), 0) AS `bytesReceived`,
coalesce(sum(`user_statistics`.`net_bytes_sent` + `user_statistics`.`current_bytes_sent`), 0) AS `bytesSent`
from
`cloud`.`user_statistics`
where
`user_statistics`.`account_id` = `account`.`id`
) AS `account_netstats` ON TRUE
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

This PR introduces a LATERAL JOIN which requires MySQL 8.0.14 or later. This is a significant change that creates a new minimum MySQL version requirement for CloudStack. This requirement should be documented in release notes, upgrade documentation, and installation documentation to ensure users are aware before upgrading. Consider adding a migration script check or warning if the MySQL version is below 8.0.14.

Suggested change
left join lateral (
select
coalesce(sum(`user_statistics`.`net_bytes_received` + `user_statistics`.`current_bytes_received`), 0) AS `bytesReceived`,
coalesce(sum(`user_statistics`.`net_bytes_sent` + `user_statistics`.`current_bytes_sent`), 0) AS `bytesSent`
from
`cloud`.`user_statistics`
where
`user_statistics`.`account_id` = `account`.`id`
) AS `account_netstats` ON TRUE
left join (
select
a.id AS `account_id`,
coalesce(sum(`us`.`net_bytes_received` + `us`.`current_bytes_received`), 0) AS `bytesReceived`,
coalesce(sum(`us`.`net_bytes_sent` + `us`.`current_bytes_sent`), 0) AS `bytesSent`
from
`cloud`.`account` a
left join `cloud`.`user_statistics` us ON us.account_id = a.id
group by a.id
) AS `account_netstats` ON `account_netstats`.`account_id` = `account`.`id`

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@DaanHoogland DaanHoogland left a comment

Choose a reason for hiding this comment

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

clgtm

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

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

4 participants