APP-925: optimize sp_d_labtest_result_postprocessing - #987
Merged
Conversation
The 'Update Inactive LAB_TEST_RESULT Records' step (line ~1785) scanned LAB_TEST and the LAB_TEST_RESULT heap. Two changes, RDB_MODERN: 1. New covering index IX_LAB_TEST_type_status_root on LAB_TEST(LAB_TEST_TYPE, RECORD_STATUS_CD) INCLUDE(ROOT_ORDERED_TEST_PNTR) - the plan's 77%-impact missing-index hint; turns the inactive-Order subquery scan into a seek. New changeset tables/263-... The plan's OTHER hint (LAB_TEST_RESULT(RECORD_STATUS_CD)) is deliberately NOT added: it is maintained on the column the downstream UPDATE flips, measured net-negative (930k vs 256k reads on that UPDATE). 2. SP content: #Inactive_Obs is now SELECT DISTINCT + a clustered PK on LAB_TEST_UID (with an ALTER COLUMN ... NOT NULL first, since SELECT INTO infers it nullable and a bare ADD PRIMARY KEY throws Msg 8111). This lets the three downstream status UPDATEs seek the temp instead of scan-joining a heap, and DISTINCT avoids write-amplification under LAB_TEST_UID fan-out. ~29% faster under parallelism on a 2M/2M worst-case repro (4.40s -> 3.11s); larger in steady state where the scan dominates. Output byte-identical (final RECORD_STATUS_CD state of LAB_TEST_RESULT/LAB_RESULT_VAL/LAB_RESULT_COMMENT, original vs optimized). SP is runOnChange:true.
Three golden-file cases asserting the final RECORD_STATUS_CD state (this SP mutates status): - app925_labtest_inactive_order: inactive Order -> its active Result + LAB_RESULT_VAL/COMMENT flip to INACTIVE - app925_labtest_active_order: active Order -> Result stays ACTIVE (no false inactivation) - app925_labtest_already_inactive: already-inactive -> unchanged (idempotent, guarded) Goldens validated byte-identical against the original SP; suite passes 3/3. Distinct key bands per case (SP commits internally), sentinel @pLabResultList so upstream key-gen stays a no-op.
…ze-labtest-result-sp # Conflicts: # reporting-pipeline-service/src/main/resources/db/changelog/migrations/v7.13/rdb/rdb.changelog-7.13.yaml
ericnagel
requested changes
Aug 10, 2026
…rations/v7.13/rdb/rdb.changelog-7.13.yaml Co-authored-by: Eric Nagel <eric.nagel@skylight.digital>
Resolve rdb.changelog-7.13.yaml conflict: rel-7.13 added changesets 263, 264-lab100-index, 371-sp_lab100_cleanup and 265 at the same append point. Keep all of them and renumber the APP-925 index migration 264 -> 266 to clear the filename collision with 264-lab100-index.sql.
ericnagel
approved these changes
Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Optimizes
sp_d_labtest_result_postprocessing's "Update Inactive LAB_TEST_RESULT Records" step(line ~1785), which scanned
LAB_TESTand theLAB_TEST_RESULTheap. Two RDB_MODERN changes:IX_LAB_TEST_type_status_rootonLAB_TEST(LAB_TEST_TYPE, RECORD_STATUS_CD) INCLUDE(ROOT_ORDERED_TEST_PNTR)— the plan's 77%-impact missing-index hint; turns theinactive-Order subquery scan into a seek (changeset
tables/264-…).#Inactive_Obsis nowSELECT DISTINCT+ a clustered PK onLAB_TEST_UID, so thethree downstream status UPDATEs seek the temp instead of scan-joining a heap.
~29% faster under parallelism on a 2M/2M worst-case repro (4.40s → 3.11s); larger in steady state,
where the line-1785 scan dominates. Output byte-identical.
Related Issue
APP-925
Additional Notes
case), so the win is modest vs a scan-bound query — the index helps most in steady state.
LAB_TEST_RESULT(RECORD_STATUS_CD)) is deliberately not added: itis maintained on the very column the UPDATE flips, and measured net-negative (930k vs 256k reads
on that UPDATE).
RECORD_STATUS_CDofLAB_TEST_RESULT/LAB_RESULT_VAL/LAB_RESULT_COMMENTis byte-identical original-vs-optimized.runOnChange: true. Index changeset is numbered264(sits above the263used by the sibling APP-926 PR APP-926: optimize sp_morbidity_report_datamart_postprocessing #980, so the two don't collide).
Checklist
DataDrivenUnitTestscases (inactive-order flip, active-order stays,already-inactive idempotent), passing 3/3, goldens validated against the original SP.