|
|
|
|
@ -1,469 +0,0 @@
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能01:查询医生排班号源
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
SELECT schedule_id, slot_no, remaining_appointments
|
|
|
|
|
FROM schedule
|
|
|
|
|
WHERE doctor_id = '550e8400-e29b-41d4-a716-446655440000'
|
|
|
|
|
AND work_date = '2024-12-15'
|
|
|
|
|
AND remaining_appointments > 0;
|
|
|
|
|
```
|
|
|
|
|
Index Scan using schedule_doctor_id_work_date_slot_no_key on hms.schedule (cost=0.29..8.31 rows=1 width=22) (actual time=0.042..0.042 rows=0 loops=1)
|
|
|
|
|
" Output: schedule_id, slot_no, remaining_appointments"
|
|
|
|
|
Index Cond: ((schedule.doctor_id = '550e8400-e29b-41d4-a716-446655440000'::uuid) AND (schedule.work_date = '2024-12-15'::date))
|
|
|
|
|
Filter: (schedule.remaining_appointments > 0)
|
|
|
|
|
Planning Time: 0.201 ms
|
|
|
|
|
Execution Time: 0.063 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能02:扣减排班号源
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
UPDATE schedule SET remaining_appointments = remaining_appointments - 1
|
|
|
|
|
WHERE schedule_id = '550e8400-e29b-41d4-a716-446655440001';
|
|
|
|
|
```
|
|
|
|
|
Update on hms.schedule (cost=0.29..8.31 rows=0 width=0) (actual time=0.026..0.026 rows=0 loops=1)
|
|
|
|
|
-> Index Scan using schedule_pkey on hms.schedule (cost=0.29..8.31 rows=1 width=10) (actual time=0.018..0.018 rows=0 loops=1)
|
|
|
|
|
" Output: (remaining_appointments - 1), ctid"
|
|
|
|
|
Index Cond: (schedule.schedule_id = '550e8400-e29b-41d4-a716-446655440001'::uuid)
|
|
|
|
|
Planning Time: 0.095 ms
|
|
|
|
|
Execution Time: 0.245 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能03:创建预约记录
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
INSERT INTO appointment (appointment_id, patient_id, schedule_id, appointment_time, status)
|
|
|
|
|
VALUES (gen_random_uuid(), '89c5bb83-c039-4619-b458-7afe7a31fc64',
|
|
|
|
|
'8510e8ab-37eb-4b12-b69d-f24c076845ca',
|
|
|
|
|
'2024-12-15 09:30:00', 'scheduled');
|
|
|
|
|
```
|
|
|
|
|
Insert on hms.appointment (cost=0.00..0.02 rows=0 width=0) (actual time=0.078..0.078 rows=0 loops=1)
|
|
|
|
|
-> Result (cost=0.00..0.02 rows=1 width=704) (actual time=0.018..0.018 rows=1 loops=1)
|
|
|
|
|
" Output: gen_random_uuid(), '89c5bb83-c039-4619-b458-7afe7a31fc64'::uuid, '8510e8ab-37eb-4b12-b69d-f24c076845ca'::uuid, '2024-12-15 09:30:00'::timestamp without time zone, 'scheduled'::character varying(20), 'online'::character varying(20), CURRENT_TIMESTAMP, NULL::timestamp without time zone, NULL::character varying(255)"
|
|
|
|
|
Planning Time: 0.022 ms
|
|
|
|
|
Trigger RI_ConstraintTrigger_c_27573 for constraint fk_apt_patient: time=0.082 calls=1
|
|
|
|
|
Trigger RI_ConstraintTrigger_c_27578 for constraint fk_apt_schedule: time=0.044 calls=1
|
|
|
|
|
Execution Time: 0.215 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能04:查询医生当日待诊列表
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
SELECT a.appointment_id, p.name AS patient_name, a.appointment_time
|
|
|
|
|
FROM appointment a
|
|
|
|
|
JOIN patient p ON a.patient_id = p.patient_id
|
|
|
|
|
JOIN schedule s ON a.schedule_id = s.schedule_id
|
|
|
|
|
WHERE s.doctor_id = '550e8400-e29b-41d4-a716-446655440004'
|
|
|
|
|
AND s.work_date = '2024-12-15'
|
|
|
|
|
AND a.status = 'scheduled'
|
|
|
|
|
ORDER BY a.appointment_time;
|
|
|
|
|
```
|
|
|
|
|
Sort (cost=731.51..731.52 rows=1 width=32) (actual time=0.087..0.090 rows=0 loops=1)
|
|
|
|
|
" Output: a.appointment_id, p.name, a.appointment_time"
|
|
|
|
|
Sort Key: a.appointment_time
|
|
|
|
|
Sort Method: quicksort Memory: 25kB
|
|
|
|
|
-> Nested Loop (cost=8.60..731.50 rows=1 width=32) (actual time=0.053..0.055 rows=0 loops=1)
|
|
|
|
|
" Output: a.appointment_id, p.name, a.appointment_time"
|
|
|
|
|
Inner Unique: true
|
|
|
|
|
-> Hash Join (cost=8.32..731.09 rows=1 width=40) (actual time=0.052..0.054 rows=0 loops=1)
|
|
|
|
|
" Output: a.appointment_id, a.appointment_time, a.patient_id"
|
|
|
|
|
Inner Unique: true
|
|
|
|
|
Hash Cond: (a.schedule_id = s.schedule_id)
|
|
|
|
|
-> Seq Scan on hms.appointment a (cost=0.00..696.50 rows=10008 width=56) (actual time=0.028..0.028 rows=1 loops=1)
|
|
|
|
|
" Output: a.appointment_id, a.patient_id, a.schedule_id, a.appointment_time, a.status, a.booking_channel, a.created_at, a.cancelled_at, a.cancel_reason"
|
|
|
|
|
Filter: ((a.status)::text = 'scheduled'::text)
|
|
|
|
|
Rows Removed by Filter: 4
|
|
|
|
|
-> Hash (cost=8.31..8.31 rows=1 width=16) (actual time=0.014..0.015 rows=0 loops=1)
|
|
|
|
|
Output: s.schedule_id
|
|
|
|
|
Buckets: 1024 Batches: 1 Memory Usage: 8kB
|
|
|
|
|
-> Index Scan using schedule_doctor_id_work_date_slot_no_key on hms.schedule s (cost=0.29..8.31 rows=1 width=16) (actual time=0.014..0.014 rows=0 loops=1)
|
|
|
|
|
Output: s.schedule_id
|
|
|
|
|
Index Cond: ((s.doctor_id = '550e8400-e29b-41d4-a716-446655440004'::uuid) AND (s.work_date = '2024-12-15'::date))
|
|
|
|
|
-> Index Scan using patient_pkey on hms.patient p (cost=0.29..0.41 rows=1 width=24) (never executed)
|
|
|
|
|
" Output: p.patient_id, p.name, p.id_number, p.mobile, p.email, p.gender, p.birth_date, p.address, p.status, p.created_at, p.updated_at"
|
|
|
|
|
Index Cond: (p.patient_id = a.patient_id)
|
|
|
|
|
Planning Time: 1.273 ms
|
|
|
|
|
Execution Time: 0.119 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能05:更新预约状态为"已签到"
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
UPDATE appointment SET status = 'checked_in'
|
|
|
|
|
WHERE appointment_id = '550e8400-e29b-41d4-a716-446655440005';
|
|
|
|
|
```
|
|
|
|
|
Update on hms.appointment (cost=0.29..8.30 rows=0 width=0) (actual time=0.016..0.016 rows=0 loops=1)
|
|
|
|
|
-> Index Scan using appointment_pkey on hms.appointment (cost=0.29..8.30 rows=1 width=64) (actual time=0.015..0.015 rows=0 loops=1)
|
|
|
|
|
" Output: 'checked_in'::character varying(20), ctid"
|
|
|
|
|
Index Cond: (appointment.appointment_id = '550e8400-e29b-41d4-a716-446655440005'::uuid)
|
|
|
|
|
Planning Time: 0.079 ms
|
|
|
|
|
Execution Time: 0.061 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能06:创建初始病历记录
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
INSERT INTO medical_record (record_id, patient_id, doctor_id, appointment_id, visit_time)
|
|
|
|
|
VALUES (gen_random_uuid(), '5e8d512a-22c9-4272-9cc7-b5b602b447c6',
|
|
|
|
|
'51e660c9-8270-439b-b33a-12230b5f27b2',
|
|
|
|
|
'3221a9b3-05e2-4375-92ce-f395ca05115f',
|
|
|
|
|
CURRENT_TIMESTAMP);
|
|
|
|
|
```
|
|
|
|
|
Insert on hms.medical_record (cost=0.00..0.03 rows=0 width=0) (actual time=0.068..0.069 rows=0 loops=1)
|
|
|
|
|
-> Result (cost=0.00..0.03 rows=1 width=1312) (actual time=0.024..0.024 rows=1 loops=1)
|
|
|
|
|
" Output: gen_random_uuid(), '5e8d512a-22c9-4272-9cc7-b5b602b447c6'::uuid, '51e660c9-8270-439b-b33a-12230b5f27b2'::uuid, '3221a9b3-05e2-4375-92ce-f395ca05115f'::uuid, CURRENT_TIMESTAMP, NULL::text, NULL::text, NULL::text, NULL::character varying(255), NULL::character varying(255), NULL::text, NULL::text, NULL::text, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP"
|
|
|
|
|
Planning Time: 0.023 ms
|
|
|
|
|
Trigger RI_ConstraintTrigger_c_27594 for constraint fk_record_patient: time=0.112 calls=1
|
|
|
|
|
Trigger RI_ConstraintTrigger_c_27599 for constraint fk_record_doctor: time=0.056 calls=1
|
|
|
|
|
Trigger RI_ConstraintTrigger_c_27604 for constraint fk_record_appointment: time=0.558 calls=1
|
|
|
|
|
Execution Time: 0.813 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能07:更新病历诊断信息
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
UPDATE medical_record
|
|
|
|
|
SET chief_complaint = '头痛、发热3天',
|
|
|
|
|
diagnosis_codes = '上呼吸道感染,高血压',
|
|
|
|
|
updated_at = CURRENT_TIMESTAMP
|
|
|
|
|
WHERE record_id = '550e8400-e29b-41d4-a716-446655440009';
|
|
|
|
|
```
|
|
|
|
|
Update on hms.medical_record (cost=0.29..8.31 rows=0 width=0) (actual time=0.022..0.022 rows=0 loops=1)
|
|
|
|
|
-> Index Scan using medical_record_pkey on hms.medical_record (cost=0.29..8.31 rows=1 width=562) (actual time=0.020..0.020 rows=0 loops=1)
|
|
|
|
|
" Output: '头痛、发热3天'::text, '上呼吸道感染,高血压'::character varying(255), CURRENT_TIMESTAMP, ctid"
|
|
|
|
|
Index Cond: (medical_record.record_id = '550e8400-e29b-41d4-a716-446655440009'::uuid)
|
|
|
|
|
Planning Time: 0.064 ms
|
|
|
|
|
Execution Time: 0.056 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能08:创建处方主记录
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
INSERT INTO prescription (prescription_id, record_id, doctor_id, status)
|
|
|
|
|
VALUES ('5fcd0fcb-e522-43fb-b82e-8270c70aeb03', '05e5fe94-6b58-4e08-ae06-fc6990793c29',
|
|
|
|
|
'0193cd15-f4c4-4331-beaa-01fb67a3d00c', 'pending');
|
|
|
|
|
```
|
|
|
|
|
Insert on hms.prescription (cost=0.00..0.01 rows=0 width=0) (actual time=1.102..1.102 rows=0 loops=1)
|
|
|
|
|
-> Result (cost=0.00..0.01 rows=1 width=138) (actual time=0.002..0.003 rows=1 loops=1)
|
|
|
|
|
" Output: '5fcd0fcb-e522-43fb-b82e-8270c70aeb03'::uuid, '05e5fe94-6b58-4e08-ae06-fc6990793c29'::uuid, '0193cd15-f4c4-4331-beaa-01fb67a3d00c'::uuid, CURRENT_TIMESTAMP, 'pending'::character varying(20), NULL::uuid, NULL::timestamp without time zone"
|
|
|
|
|
Planning Time: 0.020 ms
|
|
|
|
|
Trigger RI_ConstraintTrigger_c_27620 for constraint fk_prescription_record: time=0.083 calls=1
|
|
|
|
|
Trigger RI_ConstraintTrigger_c_27625 for constraint fk_prescription_doctor: time=0.094 calls=1
|
|
|
|
|
Execution Time: 1.288 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能09:添加处方明细项
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
INSERT INTO prescription_item (item_id, prescription_id, drug_id, dosage, frequency, duration_days, quantity)
|
|
|
|
|
VALUES (gen_random_uuid(), '550e8400-e29b-51d4-a716-446655440012',
|
|
|
|
|
'550e8400-e29b-41d4-a716-446655440013',
|
|
|
|
|
'1片', '每日3次', 7, 21);
|
|
|
|
|
```
|
|
|
|
|
Insert on hms.prescription_item (cost=0.00..0.01 rows=0 width=0) (actual time=0.087..0.088 rows=0 loops=1)
|
|
|
|
|
-> Result (cost=0.00..0.01 rows=1 width=356) (actual time=0.019..0.019 rows=1 loops=1)
|
|
|
|
|
" Output: gen_random_uuid(), '550e8400-e29b-51d4-a716-446655440012'::uuid, '550e8400-e29b-41d4-a716-446655440013'::uuid, '1片'::character varying(50), '每日3次'::character varying(50), 7, 21, NULL::text, NULL::numeric(10,2), NULL::numeric(10,2)"
|
|
|
|
|
Planning Time: 0.025 ms
|
|
|
|
|
Execution Time: 0.102 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能10:查询处方明细清单
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
SELECT d.generic_name, i.dosage, i.frequency, i.quantity
|
|
|
|
|
FROM prescription_item i
|
|
|
|
|
JOIN drug d ON i.drug_id = d.drug_id
|
|
|
|
|
WHERE i.prescription_id = '550e8400-e29b-41d4-a716-446655440014';
|
|
|
|
|
```
|
|
|
|
|
Nested Loop (cost=4.71..40.80 rows=3 width=30) (actual time=0.358..0.358 rows=0 loops=1)
|
|
|
|
|
" Output: d.generic_name, i.dosage, i.frequency, i.quantity"
|
|
|
|
|
Inner Unique: true
|
|
|
|
|
-> Bitmap Heap Scan on hms.prescription_item i (cost=4.44..15.91 rows=3 width=37) (actual time=0.357..0.357 rows=0 loops=1)
|
|
|
|
|
" Output: i.item_id, i.prescription_id, i.drug_id, i.dosage, i.frequency, i.duration_days, i.quantity, i.instructions, i.price, i.amount"
|
|
|
|
|
Recheck Cond: (i.prescription_id = '550e8400-e29b-41d4-a716-446655440014'::uuid)
|
|
|
|
|
-> Bitmap Index Scan on prescription_item_prescription_id_drug_id_key (cost=0.00..4.44 rows=3 width=0) (actual time=0.339..0.339 rows=0 loops=1)
|
|
|
|
|
Index Cond: (i.prescription_id = '550e8400-e29b-41d4-a716-446655440014'::uuid)
|
|
|
|
|
-> Index Scan using drug_pkey on hms.drug d (cost=0.28..8.29 rows=1 width=25) (never executed)
|
|
|
|
|
" Output: d.drug_id, d.generic_name, d.trade_name, d.specification, d.unit, d.dosage_form, d.manufacturer, d.approval_no, d.is_prescription, d.shelf_life_days, d.storage_conditions, d.created_at"
|
|
|
|
|
Index Cond: (d.drug_id = i.drug_id)
|
|
|
|
|
Planning Time: 0.342 ms
|
|
|
|
|
Execution Time: 0.376 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能11:更新处方审核状态
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
UPDATE prescription SET status = 'approved',
|
|
|
|
|
pharmacist_id = '550e8400-e29b-41d4-a716-446655440015',
|
|
|
|
|
reviewed_at = CURRENT_TIMESTAMP
|
|
|
|
|
WHERE prescription_id = '550e8400-e29b-41d4-a716-446655440016';
|
|
|
|
|
```
|
|
|
|
|
Update on hms.prescription (cost=0.29..8.31 rows=0 width=0) (actual time=0.015..0.015 rows=0 loops=1)
|
|
|
|
|
-> Index Scan using prescription_pkey on hms.prescription (cost=0.29..8.31 rows=1 width=88) (actual time=0.014..0.014 rows=0 loops=1)
|
|
|
|
|
" Output: 'approved'::character varying(20), '550e8400-e29b-41d4-a716-446655440015'::uuid, CURRENT_TIMESTAMP, ctid"
|
|
|
|
|
Index Cond: (prescription.prescription_id = '550e8400-e29b-41d4-a716-446655440016'::uuid)
|
|
|
|
|
Planning Time: 0.075 ms
|
|
|
|
|
Execution Time: 0.042 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能12:查询药品库存可用数量
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
SELECT SUM(current_stock) AS total_stock
|
|
|
|
|
FROM inventory_batch
|
|
|
|
|
WHERE drug_id = '550e8400-e29b-41d4-a716-446655440017';
|
|
|
|
|
```
|
|
|
|
|
Aggregate (cost=149.51..149.52 rows=1 width=8) (actual time=0.500..0.500 rows=1 loops=1)
|
|
|
|
|
Output: sum(current_stock)
|
|
|
|
|
-> Seq Scan on hms.inventory_batch (cost=0.00..149.50 rows=5 width=4) (actual time=0.494..0.494 rows=0 loops=1)
|
|
|
|
|
" Output: batch_id, drug_id, batch_no, production_date, expiry_date, purchase_quantity, purchase_price, purchase_date, current_stock, department_id, min_stock_threshold, last_stock_in, last_stock_out"
|
|
|
|
|
Filter: (inventory_batch.drug_id = '550e8400-e29b-41d4-a716-446655440017'::uuid)
|
|
|
|
|
Rows Removed by Filter: 5000
|
|
|
|
|
Planning Time: 0.131 ms
|
|
|
|
|
Execution Time: 0.515 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能13:扣减药品库存
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 查询符合条件的批次(用于查看执行计划)
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
SELECT batch_id FROM inventory_batch
|
|
|
|
|
WHERE drug_id = '550e8400-e29b-41d4-a716-446655440018'
|
|
|
|
|
AND current_stock >= 10
|
|
|
|
|
ORDER BY expiry_date ASC LIMIT 1;
|
|
|
|
|
```
|
|
|
|
|
Limit (cost=162.03..162.03 rows=1 width=20) (actual time=0.537..0.538 rows=0 loops=1)
|
|
|
|
|
" Output: batch_id, expiry_date"
|
|
|
|
|
-> Sort (cost=162.03..162.04 rows=5 width=20) (actual time=0.536..0.536 rows=0 loops=1)
|
|
|
|
|
" Output: batch_id, expiry_date"
|
|
|
|
|
Sort Key: inventory_batch.expiry_date
|
|
|
|
|
Sort Method: quicksort Memory: 25kB
|
|
|
|
|
-> Seq Scan on hms.inventory_batch (cost=0.00..162.00 rows=5 width=20) (actual time=0.525..0.525 rows=0 loops=1)
|
|
|
|
|
" Output: batch_id, expiry_date"
|
|
|
|
|
Filter: ((inventory_batch.current_stock >= 10) AND (inventory_batch.drug_id = '550e8400-e29b-41d4-a716-446655440018'::uuid))
|
|
|
|
|
Rows Removed by Filter: 5000
|
|
|
|
|
Planning Time: 0.127 ms
|
|
|
|
|
Execution Time: 0.550 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能14:更新处方状态为"已发药"
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
UPDATE prescription SET status = 'dispensed'
|
|
|
|
|
WHERE prescription_id = '550e8400-e29b-41d4-a716-446655440020';
|
|
|
|
|
```
|
|
|
|
|
Update on hms.prescription (cost=0.29..8.30 rows=0 width=0) (actual time=0.015..0.015 rows=0 loops=1)
|
|
|
|
|
-> Index Scan using prescription_pkey on hms.prescription (cost=0.29..8.30 rows=1 width=64) (actual time=0.014..0.014 rows=0 loops=1)
|
|
|
|
|
" Output: 'dispensed'::character varying(20), ctid"
|
|
|
|
|
Index Cond: (prescription.prescription_id = '550e8400-e29b-41d4-a716-446655440020'::uuid)
|
|
|
|
|
Planning Time: 0.080 ms
|
|
|
|
|
Execution Time: 0.031 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能15:取消预约并回退号源
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 更新预约状态
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
UPDATE appointment SET status = 'cancelled', cancelled_at = CURRENT_TIMESTAMP
|
|
|
|
|
WHERE appointment_id = '550e8400-e29b-41d4-a716-446655440021';
|
|
|
|
|
```
|
|
|
|
|
Update on hms.appointment (cost=0.29..8.31 rows=0 width=0) (actual time=0.014..0.014 rows=0 loops=1)
|
|
|
|
|
-> Index Scan using appointment_pkey on hms.appointment (cost=0.29..8.31 rows=1 width=72) (actual time=0.013..0.013 rows=0 loops=1)
|
|
|
|
|
" Output: 'cancelled'::character varying(20), CURRENT_TIMESTAMP, ctid"
|
|
|
|
|
Index Cond: (appointment.appointment_id = '550e8400-e29b-41d4-a716-446655440021'::uuid)
|
|
|
|
|
Planning Time: 0.062 ms
|
|
|
|
|
Execution Time: 0.029 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- 回退号源(子查询版本)
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
UPDATE schedule SET remaining_appointments = remaining_appointments + 1
|
|
|
|
|
WHERE schedule_id = (SELECT schedule_id FROM appointment
|
|
|
|
|
WHERE appointment_id = '550e8400-e29b-41d4-a716-446655440022');
|
|
|
|
|
```
|
|
|
|
|
Update on hms.schedule (cost=8.59..16.61 rows=0 width=0) (actual time=0.019..0.019 rows=0 loops=1)
|
|
|
|
|
InitPlan 1
|
|
|
|
|
-> Index Scan using appointment_pkey on hms.appointment (cost=0.29..8.30 rows=1 width=16) (actual time=0.007..0.007 rows=0 loops=1)
|
|
|
|
|
Output: appointment.schedule_id
|
|
|
|
|
Index Cond: (appointment.appointment_id = '550e8400-e29b-41d4-a716-446655440022'::uuid)
|
|
|
|
|
-> Index Scan using schedule_pkey on hms.schedule (cost=0.29..8.31 rows=1 width=10) (actual time=0.018..0.018 rows=0 loops=1)
|
|
|
|
|
" Output: (schedule.remaining_appointments + 1), schedule.ctid"
|
|
|
|
|
Index Cond: (schedule.schedule_id = (InitPlan 1).col1)
|
|
|
|
|
Planning Time: 0.101 ms
|
|
|
|
|
Execution Time: 0.038 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能16:查询库存预警药品
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
SELECT d.generic_name, SUM(ib.current_stock) AS total_stock
|
|
|
|
|
FROM drug d
|
|
|
|
|
JOIN inventory_batch ib ON d.drug_id = ib.drug_id
|
|
|
|
|
GROUP BY d.drug_id, d.generic_name, ib.min_stock_threshold
|
|
|
|
|
HAVING SUM(ib.current_stock) < ib.min_stock_threshold;
|
|
|
|
|
```
|
|
|
|
|
HashAggregate (cost=234.18..284.18 rows=1333 width=37) (actual time=1.724..1.869 rows=14 loops=1)
|
|
|
|
|
" Output: d.generic_name, sum(ib.current_stock), d.drug_id, ib.min_stock_threshold"
|
|
|
|
|
" Group Key: d.drug_id, ib.min_stock_threshold"
|
|
|
|
|
Filter: (sum(ib.current_stock) < ib.min_stock_threshold)
|
|
|
|
|
Batches: 1 Memory Usage: 721kB
|
|
|
|
|
Rows Removed by Filter: 2896
|
|
|
|
|
-> Hash Join (cost=46.50..196.68 rows=5000 width=33) (actual time=0.197..1.071 rows=5000 loops=1)
|
|
|
|
|
" Output: d.drug_id, ib.min_stock_threshold, d.generic_name, ib.current_stock"
|
|
|
|
|
Inner Unique: true
|
|
|
|
|
Hash Cond: (ib.drug_id = d.drug_id)
|
|
|
|
|
-> Seq Scan on hms.inventory_batch ib (cost=0.00..137.00 rows=5000 width=24) (actual time=0.006..0.167 rows=5000 loops=1)
|
|
|
|
|
" Output: ib.batch_id, ib.drug_id, ib.batch_no, ib.production_date, ib.expiry_date, ib.purchase_quantity, ib.purchase_price, ib.purchase_date, ib.current_stock, ib.department_id, ib.min_stock_threshold, ib.last_stock_in, ib.last_stock_out"
|
|
|
|
|
-> Hash (cost=34.00..34.00 rows=1000 width=25) (actual time=0.185..0.185 rows=1000 loops=1)
|
|
|
|
|
" Output: d.generic_name, d.drug_id"
|
|
|
|
|
Buckets: 1024 Batches: 1 Memory Usage: 65kB
|
|
|
|
|
-> Seq Scan on hms.drug d (cost=0.00..34.00 rows=1000 width=25) (actual time=0.006..0.113 rows=1000 loops=1)
|
|
|
|
|
" Output: d.generic_name, d.drug_id"
|
|
|
|
|
Planning Time: 0.155 ms
|
|
|
|
|
Execution Time: 1.989 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能17:统计科室预约量
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
SELECT dep.name, COUNT(a.appointment_id) as appointment_count
|
|
|
|
|
FROM department dep
|
|
|
|
|
JOIN doctor d ON dep.department_id = d.department_id
|
|
|
|
|
JOIN schedule s ON d.doctor_id = s.doctor_id
|
|
|
|
|
LEFT JOIN appointment a ON s.schedule_id = a.schedule_id
|
|
|
|
|
WHERE s.work_date = '2024-12-15'
|
|
|
|
|
GROUP BY dep.department_id, dep.name;
|
|
|
|
|
```
|
|
|
|
|
GroupAggregate (cost=1379.43..1379.45 rows=1 width=242) (actual time=2.454..2.459 rows=0 loops=1)
|
|
|
|
|
" Output: dep.name, count(a.appointment_id), dep.department_id"
|
|
|
|
|
Group Key: dep.department_id
|
|
|
|
|
-> Sort (cost=1379.43..1379.44 rows=1 width=250) (actual time=2.453..2.457 rows=0 loops=1)
|
|
|
|
|
" Output: dep.department_id, dep.name, a.appointment_id"
|
|
|
|
|
Sort Key: dep.department_id
|
|
|
|
|
Sort Method: quicksort Memory: 25kB
|
|
|
|
|
-> Nested Loop (cost=671.72..1379.42 rows=1 width=250) (actual time=2.436..2.440 rows=0 loops=1)
|
|
|
|
|
" Output: dep.department_id, dep.name, a.appointment_id"
|
|
|
|
|
Inner Unique: true
|
|
|
|
|
-> Nested Loop (cost=671.58..1379.24 rows=1 width=32) (actual time=2.436..2.439 rows=0 loops=1)
|
|
|
|
|
" Output: d.department_id, a.appointment_id"
|
|
|
|
|
Inner Unique: true
|
|
|
|
|
-> Hash Right Join (cost=671.30..1370.94 rows=1 width=32) (actual time=2.435..2.438 rows=0 loops=1)
|
|
|
|
|
" Output: s.doctor_id, a.appointment_id"
|
|
|
|
|
Inner Unique: true
|
|
|
|
|
Hash Cond: (a.schedule_id = s.schedule_id)
|
|
|
|
|
-> Seq Scan on hms.appointment a (cost=0.00..634.00 rows=25000 width=32) (never executed)
|
|
|
|
|
" Output: a.appointment_id, a.patient_id, a.schedule_id, a.appointment_time, a.status, a.booking_channel, a.created_at, a.cancelled_at, a.cancel_reason"
|
|
|
|
|
-> Hash (cost=671.29..671.29 rows=1 width=32) (actual time=2.428..2.430 rows=0 loops=1)
|
|
|
|
|
" Output: s.doctor_id, s.schedule_id"
|
|
|
|
|
Buckets: 1024 Batches: 1 Memory Usage: 8kB
|
|
|
|
|
-> Seq Scan on hms.schedule s (cost=0.00..671.29 rows=1 width=32) (actual time=2.427..2.427 rows=0 loops=1)
|
|
|
|
|
" Output: s.doctor_id, s.schedule_id"
|
|
|
|
|
Filter: (s.work_date = '2024-12-15'::date)
|
|
|
|
|
Rows Removed by Filter: 27703
|
|
|
|
|
-> Index Scan using doctor_pkey on hms.doctor d (cost=0.28..8.29 rows=1 width=32) (never executed)
|
|
|
|
|
" Output: d.doctor_id, d.department_id, d.name, d.title, d.license_no, d.contact, d.work_status"
|
|
|
|
|
Index Cond: (d.doctor_id = s.doctor_id)
|
|
|
|
|
-> Index Scan using department_pkey on hms.department dep (cost=0.14..0.18 rows=1 width=234) (never executed)
|
|
|
|
|
" Output: dep.department_id, dep.code, dep.name, dep.location, dep.phone"
|
|
|
|
|
Index Cond: (dep.department_id = d.department_id)
|
|
|
|
|
Planning Time: 0.311 ms
|
|
|
|
|
Execution Time: 2.495 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- 功能18:统计医生工作量
|
|
|
|
|
-- ============================================
|
|
|
|
|
EXPLAIN (ANALYZE, VERBOSE)
|
|
|
|
|
SELECT d.name, COUNT(mr.record_id) as record_count
|
|
|
|
|
FROM doctor d
|
|
|
|
|
LEFT JOIN medical_record mr ON d.doctor_id = mr.doctor_id
|
|
|
|
|
AND EXTRACT(YEAR FROM mr.visit_time) = 2024
|
|
|
|
|
AND EXTRACT(MONTH FROM mr.visit_time) = 12
|
|
|
|
|
WHERE d.work_status = 'active'
|
|
|
|
|
GROUP BY d.doctor_id, d.name;
|
|
|
|
|
```
|
|
|
|
|
GroupAggregate (cost=5247.03..5270.93 rows=1194 width=32) (actual time=13.444..14.002 rows=1194 loops=1)
|
|
|
|
|
" Output: d.name, count(mr.record_id), d.doctor_id"
|
|
|
|
|
Group Key: d.doctor_id
|
|
|
|
|
-> Merge Left Join (cost=5247.03..5253.02 rows=1194 width=40) (actual time=13.439..13.643 rows=1295 loops=1)
|
|
|
|
|
" Output: d.doctor_id, d.name, mr.record_id"
|
|
|
|
|
Merge Cond: (d.doctor_id = mr.doctor_id)
|
|
|
|
|
-> Sort (cost=114.02..117.01 rows=1194 width=24) (actual time=0.345..0.384 rows=1194 loops=1)
|
|
|
|
|
" Output: d.name, d.doctor_id"
|
|
|
|
|
Sort Key: d.doctor_id
|
|
|
|
|
Sort Method: quicksort Memory: 98kB
|
|
|
|
|
-> Seq Scan on hms.doctor d (cost=0.00..53.00 rows=1194 width=24) (actual time=0.006..0.200 rows=1194 loops=1)
|
|
|
|
|
" Output: d.name, d.doctor_id"
|
|
|
|
|
Filter: ((d.work_status)::text = 'active'::text)
|
|
|
|
|
Rows Removed by Filter: 806
|
|
|
|
|
-> Sort (cost=5133.01..5133.02 rows=1 width=32) (actual time=13.090..13.111 rows=865 loops=1)
|
|
|
|
|
" Output: mr.record_id, mr.doctor_id"
|
|
|
|
|
Sort Key: mr.doctor_id
|
|
|
|
|
Sort Method: quicksort Memory: 65kB
|
|
|
|
|
-> Seq Scan on hms.medical_record mr (cost=0.00..5133.00 rows=1 width=32) (actual time=0.016..12.946 rows=865 loops=1)
|
|
|
|
|
" Output: mr.record_id, mr.doctor_id"
|
|
|
|
|
Filter: ((EXTRACT(year FROM mr.visit_time) = '2024'::numeric) AND (EXTRACT(month FROM mr.visit_time) = '12'::numeric))
|
|
|
|
|
Rows Removed by Filter: 19136
|
|
|
|
|
Planning Time: 0.171 ms
|
|
|
|
|
Execution Time: 14.051 ms
|
|
|
|
|
```sql
|
|
|
|
|
-- 1. 各表数据量统计
|
|
|
|
|
SELECT 'department' as table_name, COUNT(*) as row_count FROM department
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'doctor', COUNT(*) FROM doctor
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'patient', COUNT(*) FROM patient
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'drug', COUNT(*) FROM drug
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'inventory_batch', COUNT(*) FROM inventory_batch
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'schedule', COUNT(*) FROM schedule
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'appointment', COUNT(*) FROM appointment
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'medical_record', COUNT(*) FROM medical_record
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'prescription', COUNT(*) FROM prescription
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT 'prescription_item', COUNT(*) FROM prescription_item;
|
|
|
|
|
```
|
|
|
|
|
prescription_item,45002
|
|
|
|
|
medical_record,20001
|
|
|
|
|
appointment,25001
|
|
|
|
|
schedule,27703
|
|
|
|
|
prescription,18001
|
|
|
|
|
patient,10000
|
|
|
|
|
inventory_batch,5000
|
|
|
|
|
doctor,2000
|
|
|
|
|
drug,1000
|
|
|
|
|
department,50
|
|
|
|
|
```sql
|
|
|
|
|
-- 2. 现有索引检查(使用系统表)
|
|
|
|
|
SELECT
|
|
|
|
|
t.relname as table_name,
|
|
|
|
|
i.relname as index_name,
|
|
|
|
|
a.attname as column_name
|
|
|
|
|
FROM pg_class t
|
|
|
|
|
JOIN pg_index ix ON t.oid = ix.indrelid
|
|
|
|
|
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
|
|
|
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)
|
|
|
|
|
WHERE t.relkind = 'r'
|
|
|
|
|
AND t.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
|
|
|
|
|
ORDER BY t.relname, i.relname;
|
|
|
|
|
```
|
|
|
|
|
无
|
|
|
|
|
# 完整运行结果
|
|
|
|
|
| | | | | | | | | |
|
|
|
|
|
|---|---|---|---|---|---|---|---|---|
|
|
|
|
|
|SELECT (select)||||||||Planning Time = 0.375; Triggers = []; Execution Time = 0.1;|
|
|
|
|
|
|SORT (sort)||3|0|49.36|0.073|49.35|0.072|Parallel Aware = false; Async Capable = false; Plan Width = 192; Actual Loops = 1; Sort Key = ["t.relname","i.relname"]; Sort Method = quicksort; Sort Space Used = 25; Sort Space Type = Memory;|
|
|
|
|
|
|SEQ_SCAN (Seq Scan)|table: pg_namespace;|1|0|1.05|0.004|0.0|0.004|Parent Relationship = InitPlan; Subplan Name = InitPlan 1; Parallel Aware = false; Async Capable = false; Alias = pg_namespace; Plan Width = 4; Actual Loops = 1; Filter = (nspname = 'public'::name); Rows Removed by Filter = 7;|
|
|
|
|
|
|NESTED_LOOPS (Nested Loop)||3|0|48.28|0.067|21.54|0.067|Parent Relationship = Outer; Parallel Aware = false; Async Capable = false; Join Type = Inner; Plan Width = 192; Actual Loops = 1; Inner Unique = true;|
|
|
|
|
|
|NESTED_LOOPS (Nested Loop)||3|0|46.09|0.067|21.27|0.066|Parent Relationship = Outer; Parallel Aware = false; Async Capable = false; Join Type = Inner; Plan Width = 132; Actual Loops = 1; Inner Unique = false; Join Filter = (t.oid = a.attrelid); Rows Removed by Join Filter = 0;|
|
|
|
|
|
|HASH_JOIN (hash join)||7|0|28.06|0.067|20.99|0.066|Parent Relationship = Outer; Parallel Aware = false; Async Capable = false; Join Type = Inner; Plan Width = 103; Actual Loops = 1; Inner Unique = true; Hash Cond = (ix.indrelid = t.oid);|
|
|
|
|
|
|SEQ_SCAN (Seq Scan)|table: pg_index;|164|1|6.64|0.007|0.0|0.007|Parent Relationship = Outer; Parallel Aware = false; Async Capable = false; Alias = ix; Plan Width = 35; Actual Loops = 1;|
|
|
|
|
|
|TRANSFORM (Hash)||19|0|20.75|0.054|20.75|0.054|Parent Relationship = Inner; Parallel Aware = false; Async Capable = false; Plan Width = 68; Actual Loops = 1; Hash Buckets = 1024; Original Hash Buckets = 1024; Hash Batches = 1; Original Hash Batches = 1; Peak Memory Usage = 8;|
|
|
|
|
|
|SEQ_SCAN (Seq Scan)|table: pg_class;|19|0|20.75|0.054|0.0|0.054|Parent Relationship = Outer; Parallel Aware = false; Async Capable = false; Alias = t; Plan Width = 68; Actual Loops = 1; Filter = ((relkind = 'r'::"char") AND (relnamespace = (InitPlan 1).col1)); Rows Removed by Filter = 454;|
|
|
|
|
|
|INDEX_SCAN (index scan)|table: pg_attribute; index: pg_attribute_relid_attnam_index;|1|0|2.56|0.0|0.28|0.0|Parent Relationship = Inner; Parallel Aware = false; Async Capable = false; Scan Direction = Forward; Alias = a; Plan Width = 70; Actual Loops = 0; Index Cond = (attrelid = ix.indrelid); Rows Removed by Index Recheck = 0; Filter = (attnum = ANY ((ix.indkey)::smallint[])); Rows Removed by Filter = 0;|
|
|
|
|
|
|INDEX_SCAN (index scan)|table: pg_class; index: pg_class_oid_index;|1|0|0.73|0.0|0.27|0.0|Parent Relationship = Inner; Parallel Aware = false; Async Capable = false; Scan Direction = Forward; Alias = i; Plan Width = 68; Actual Loops = 0; Index Cond = (oid = ix.indexrelid); Rows Removed by Index Recheck = 0;|
|