Files
his/md/门诊就诊记录SQL优化建议.md
chenqi cb268fe26d feat(operating-room): 添加手术室类型和所属科室字段
- 新增手术室类型字段支持急诊、择期、日间、复合手术室四种类型
- 添加所属科室字段实现科室级别资源管理
- 前端列表页面新增类型和所属科室显示列
- 新增类型选择器和科室选择器组件
- 后端实体类和服务类添加对应字段处理逻辑
- 数据库添加room_type_enum字段和相关索引
- 创建手术室类型字典数据和字典项配置
- 生成手术室管理功能说明文档
2026-01-13 10:03:57 +08:00

160 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 门诊就诊记录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. 定期维护和优化索引