今天编写mapper,无意间看见了一个包含多个子查询的语句,于是引发了思考,觉得这个语句可以被优化。
SELECT t.id,t. CODE,t.`name`,t.`value`,t.company_id,c.`name` companyName,t.type,p.`name` typeName,t.create_by,
(SELECT u. NAME FROM sys_user u WHERE u.user_id = t.create_by)
createName,t.create_time,t.last_modify_by,
(SELECT u. NAME FROM sys_user u WHERE u.user_id = t.last_modify_by)
lastModifyName,t.last_modify_time,t.approve_by,
(SELECT u. NAME FROM sys_user u WHERE u.user_id = t.approve_by)
approveName,t.approve_time FROM ins_conf_detail t
LEFT JOIN ins_company c ON t.company_id = c.id
LEFT JOIN ins_conf_type p ON t.type = p.id
上面的SQL,因为包含多个select,总觉得有些不妥当,事实胜于雄辩,造数据检查性能到底行不行。
ins_conf_detail表造了约6万条数据
查询三遍,耗时分别为1.408s、1.398s、1.396s。
虽然不是很慢,但是还是有优化的空间,于是我将上述SQL改写为:
SELECT cf.id,cf.code,cf.name,cf.value,ct.code as type_code,ct.name as type_name,h.code as hospital_code,h.name as hospital_Name,cp.code as company_code,cp.name as company_name, cf.is_global
,u1.username as create_by_code,u1.name as create_by_name,cf.create_time
,u2.username as last_modify_by_code,u2.name as last_modify_by_name,cf.last_modify_time
,u3.username as approve_by_code,u3.name as approve_by_name,cf.approve_time
from ins_conf_detail cf
LEFT JOIN ins_conf_type ct ON cf.type = ct.id
LEFT JOIN ins_hospital h ON cf.hospital_id = h.id
LEFT JOIN ins_company cp ON cf.company_id = cp.id
LEFT JOIN sys_user u1 ON cf.create_by = u1.user_id
LEFT JOIN sys_user u2 ON cf.last_modify_by = u2.user_id
LEFT JOIN sys_user u3 ON cf.approve_by = u3.user_id
拼接了很多联结查询,但是最后三个联结是同一张表,而且所有联结查询的字段都是主键,默认是带索引的。
查询三次结果为:0.683s、0.637s、0.608s
速度提升约2倍!!!
虽然没有大幅度提升查询效率,但是这对于数据量很大的时候,还是有一定作用的。
结论:能用联结查询的情况下,尽量不用子查询。