說明
Web應用程序,MySQL數據庫,數據庫中有三張表:health_patient(病人表)、health_patient_account(病人賬戶表)、
health_patient_medical_history(病例表),視圖需求是,頁面分頁展示病人表及賬戶表的數據,分頁需要按照病例表中的創建時間進行排序。
關系說明:
一個health_patient(病人表)對應一個health_patient_account(病人賬戶表),一個health_patient(病人表)有多條
health_patient_medical_history(病例表)。
實現方式
SELECT
p.*,pa.*
FROM
`health_patient` p
INNER JOIN
`health_patient_medical_history` pmh
ON
pmh.patient_id = p.id
AND
pmh.`status` = 1
INNER JOIN
`health_patient_account` pa
ON
p.`id` = pa.`patient_id`
WHERE
pmh.`is_show` = 0
AND
p.`is_del` = 0
AND
pmh.hospital_id = 4
AND
p.patient_name LIKE '%%' OR p.id_card LIKE '%%'
AND
p.`id` in(
SELECT
distinct pmh.`patient_id`
FROM
`health_patient_medical_history` pmh
WHERE
pmh.`status` = 1
AND
pmh.`hospital_id` = 4
)
ORDER BY
pmh.create_time DESC
LIMIT 10
問題描述
隨著不斷得使用,數據越來越多。
數據量:
health_patient(病人表),13458條
health_patient_account(病人賬戶表),13463條,[存在垃圾數據]
health_patient_medical_history(病例表),21487條
執行上述查詢:
持續時間 1 查詢: 41.625 秒.
優化方式
1、先聯合health_patient(病人表)和
health_patient_medical_history(病例表)分頁查詢。
2、然后根據結果集中id,查詢health_patient_account(病人賬戶表),數據進行組裝。
SELECT
p.*
FROM
`health_patient` p
INNER JOIN
`health_patient_medical_history` pmh
ON
pmh.patient_id = p.id
AND
pmh.`status` = 1
WHERE
pmh.`is_show` = 0
AND
p.`is_del` = 0
AND
pmh.hospital_id = 4
AND
p.patient_name LIKE '%%' OR p.id_card LIKE '%%'
AND
p.`id` in(
SELECT
distinct pmh.`patient_id`
FROM
`health_patient_medical_history` pmh
WHERE
pmh.`status` = 1
AND
pmh.`hospital_id` = 4
)
ORDER BY
pmh.create_time DESC
LIMIT 10
持續時間 1 查詢: 0.063 秒
health_patient_account(病人賬戶表)創建索引
INDEX `patient_id` (`patient_id`) USING BTREE
EXPLAIN SELECT
*
FROM
health_patient_account
WHERE
hospital_id = 4
AND
patient_id IN (3344, 1776, 3343, 13475, 10954, 13308, 13474, 13264, 13473, 1343)
Using index condition:在5.6版本后加入的新特性(Index Condition Pushdown);
Using index condition 會先條件過濾索引,過濾完索引后找到所有符合索引條件的數據行,隨后用 WHERE 子句中的其他條件去過濾這些數據行;