# 门诊就诊记录SQL查询优化建议 ## 当前查询分析 ### 主要查询表 ```sql SELECT enc.id as encounterId, pt.name, pt.id_card, pt.bus_no as patientBusNo, enc.bus_no as encounterBusNo, pt.gender_enum, pt.phone, enc.create_time as encounterTime, enc.status_enum as subjectStatusEnum, org.name as organizationName, prac.name as doctorName FROM adm_encounter AS enc LEFT JOIN adm_organization AS org ON enc.organization_id = org.ID AND org.delete_flag = '0' LEFT JOIN adm_encounter_participant AS ep ON enc.ID = ep.encounter_id AND ep.type_code = #{participantType} AND ep.delete_flag = '0' LEFT JOIN adm_practitioner AS prac ON ep.practitioner_id = prac.ID AND prac.delete_flag = '0' LEFT JOIN adm_patient AS pt ON enc.patient_id = pt.ID AND pt.delete_flag = '0' ``` ### 常见查询条件 1. `enc.delete_flag = '0'` 2. `enc.tenant_id = ?` 3. `pt.name LIKE ?` 4. `pt.id_card LIKE ?` 5. `pt.bus_no LIKE ?` 6. `enc.bus_no LIKE ?` 7. `pt.gender_enum = ?` 8. `enc.status_enum = ?` 9. `prac.name LIKE ?` 10. `pt.phone LIKE ?` 11. `enc.create_time BETWEEN ? AND ?` ## 索引优化建议 ### 1. adm_encounter 表索引 ```sql -- 复合索引:提高查询性能 CREATE INDEX idx_encounter_tenant_delete_status ON adm_encounter(tenant_id, delete_flag, status_enum); -- 时间范围查询索引 CREATE INDEX idx_encounter_create_time ON adm_encounter(create_time); -- 业务编号查询索引 CREATE INDEX idx_encounter_bus_no ON adm_encounter(bus_no); -- 患者ID关联索引 CREATE INDEX idx_encounter_patient_id ON adm_encounter(patient_id); ``` ### 2. adm_patient 表索引 ```sql -- 姓名模糊查询索引 CREATE INDEX idx_patient_name ON adm_patient(name); -- 身份证号查询索引 CREATE INDEX idx_patient_id_card ON adm_patient(id_card); -- 业务编号查询索引 CREATE INDEX idx_patient_bus_no ON adm_patient(bus_no); -- 电话查询索引 CREATE INDEX idx_patient_phone ON adm_patient(phone); -- 复合索引:常用查询条件 CREATE INDEX idx_patient_delete_gender ON adm_patient(delete_flag, gender_enum); ``` ### 3. adm_encounter_participant 表索引 ```sql -- 复合索引:提高连接性能 CREATE INDEX idx_ep_encounter_type ON adm_encounter_participant(encounter_id, type_code, delete_flag); -- 参与者ID索引 CREATE INDEX idx_ep_practitioner ON adm_encounter_participant(practitioner_id); ``` ### 4. adm_practitioner 表索引 ```sql -- 姓名查询索引 CREATE INDEX idx_practitioner_name ON adm_practitioner(name); -- 复合索引:常用查询条件 CREATE INDEX idx_practitioner_delete_tenant ON adm_practitioner(delete_flag, tenant_id); ``` ### 5. adm_organization 表索引 ```sql -- 主键关联索引 CREATE INDEX idx_organization_id_delete ON adm_organization(id, delete_flag); ``` ## 查询优化建议 ### 1. 添加查询统计信息收集 ```sql -- 定期分析表统计信息 ANALYZE TABLE adm_encounter; ANALYZE TABLE adm_patient; ANALYZE TABLE adm_encounter_participant; ANALYZE TABLE adm_practitioner; ANALYZE TABLE adm_organization; ``` ### 2. 考虑分区表(针对大数据量) 如果 `adm_encounter` 表数据量超过100万条,考虑按时间分区: ```sql -- 按月分区 PARTITION BY RANGE (YEAR(create_time) * 100 + MONTH(create_time)) ( PARTITION p202501 VALUES LESS THAN (202501), PARTITION p202502 VALUES LESS THAN (202502), -- ... 更多分区 ); ``` ### 3. 添加覆盖索引(Covering Index) 对于常用查询字段,创建覆盖索引避免回表: ```sql CREATE INDEX idx_encounter_cover ON adm_encounter( tenant_id, delete_flag, create_time, status_enum, bus_no, patient_id ) INCLUDE (organization_id); ``` ## 执行计划检查 建议定期检查查询执行计划: ```sql EXPLAIN ANALYZE SELECT -- 完整查询语句 FROM adm_encounter AS enc -- ... 连接条件 WHERE enc.delete_flag = '0' AND enc.tenant_id = 1 -- ... 其他条件 ORDER BY enc.create_time DESC; ``` ## 监控建议 1. **慢查询监控**:监控执行时间超过1秒的查询 2. **索引使用监控**:定期检查未使用的索引 3. **表空间监控**:监控表增长和碎片情况 4. **连接性能监控**:监控JOIN操作的性能 ## 实施步骤 1. 在测试环境创建建议的索引 2. 执行查询性能测试 3. 分析执行计划,确认索引有效性 4. 在生产环境非高峰期创建索引 5. 监控生产环境性能变化 6. 定期维护和优化索引