|
2 | 2 | -- |
3 | 3 | -- $materialize drops and recreates the tables — indexes are lost. |
4 | 4 | -- Re-run this script after every $materialize call. |
| 5 | +-- |
| 6 | +-- Perf benchmark (100k patients, POC :7888, 12 measures cohort SQL, warm cache): |
| 7 | +-- without new indexes: 11.98s total |
| 8 | +-- with new indexes: 9.91s total (1.21x speedup) |
| 9 | +-- biggest win: CMS1154 1.88s → 0.54s (3.5x) from sof.patient_flat (id) alone |
5 | 10 |
|
| 11 | +-- patient_id lookups (one per measure cohort) |
| 12 | +CREATE INDEX IF NOT EXISTS idx_sof_patient_id ON sof.patient_flat(id); |
6 | 13 | CREATE INDEX IF NOT EXISTS idx_sof_encounter_patient ON sof.encounter_flat(patient_id); |
7 | | -CREATE INDEX IF NOT EXISTS idx_sof_encounter_type ON sof.encounter_flat(type_system, type_code); |
8 | 14 | CREATE INDEX IF NOT EXISTS idx_sof_condition_patient ON sof.condition_flat(patient_id); |
9 | | -CREATE INDEX IF NOT EXISTS idx_sof_condition_code ON sof.condition_flat(code_system, code); |
10 | 15 | CREATE INDEX IF NOT EXISTS idx_sof_procedure_patient ON sof.procedure_flat(patient_id); |
11 | | -CREATE INDEX IF NOT EXISTS idx_sof_procedure_code ON sof.procedure_flat(code_system, code); |
12 | 16 | CREATE INDEX IF NOT EXISTS idx_sof_observation_patient ON sof.observation_flat(patient_id); |
13 | | -CREATE INDEX IF NOT EXISTS idx_sof_observation_code ON sof.observation_flat(code_system, code); |
14 | 17 | CREATE INDEX IF NOT EXISTS idx_sof_servicerequest_patient ON sof.servicerequest_flat(patient_id); |
15 | 18 | CREATE INDEX IF NOT EXISTS idx_sof_medicationrequest_patient ON sof.medicationrequest_flat(patient_id); |
16 | 19 | CREATE INDEX IF NOT EXISTS idx_sof_devicerequest_patient ON sof.devicerequest_flat(patient_id); |
17 | 20 | CREATE INDEX IF NOT EXISTS idx_sof_bp_patient ON sof.observation_bp_flat(patient_id); |
| 21 | + |
| 22 | +-- code/system lookups (concepts JOIN per measure CTE) |
| 23 | +CREATE INDEX IF NOT EXISTS idx_sof_encounter_type ON sof.encounter_flat(type_system, type_code); |
| 24 | +CREATE INDEX IF NOT EXISTS idx_sof_condition_code ON sof.condition_flat(code_system, code); |
| 25 | +CREATE INDEX IF NOT EXISTS idx_sof_procedure_code ON sof.procedure_flat(code_system, code); |
| 26 | +CREATE INDEX IF NOT EXISTS idx_sof_observation_code ON sof.observation_flat(code_system, code); |
| 27 | +CREATE INDEX IF NOT EXISTS idx_sof_observation_value ON sof.observation_flat(value_system, value_code); |
| 28 | +CREATE INDEX IF NOT EXISTS idx_sof_servicerequest_code ON sof.servicerequest_flat(code_system, code); |
| 29 | +CREATE INDEX IF NOT EXISTS idx_sof_medicationrequest_med ON sof.medicationrequest_flat(med_system, med_code); |
| 30 | +CREATE INDEX IF NOT EXISTS idx_sof_devicerequest_code ON sof.devicerequest_flat(code_system, code); |
| 31 | + |
| 32 | +-- Composite covering (patient+code in one access path — encounter & condition are hottest) |
| 33 | +CREATE INDEX IF NOT EXISTS idx_sof_encounter_patient_type ON sof.encounter_flat(patient_id, type_system, type_code); |
| 34 | +CREATE INDEX IF NOT EXISTS idx_sof_condition_patient_code ON sof.condition_flat(patient_id, code_system, code); |
| 35 | + |
| 36 | +-- ANALYZE so planner has fresh row estimates immediately after $materialize. |
| 37 | +-- Autovacuum picks up eventually but explicit ANALYZE removes the lag. |
| 38 | +ANALYZE sof.patient_flat, sof.encounter_flat, sof.condition_flat, |
| 39 | + sof.procedure_flat, sof.observation_flat, sof.observation_bp_flat, |
| 40 | + sof.servicerequest_flat, sof.medicationrequest_flat, sof.devicerequest_flat; |
0 commit comments