您的位置:首页 > 数据库

业务层遍历单表查询与使用mybatis的collection实现一对多查询的效率对比

2017-12-18 16:36 1081 查看
由于公司急着上版本,一周的时间写两个模块,终于告一段落,但是里面还是有可待优化的内容。趁此间歇,将优化前后的查询做一次效率对比。

场景一:一对多查询

涉及表:医馆表,图片表,医馆图片关系表

查询结果:一个医馆对象里有一个含多个图片的集合,还有一个含多个领域的集合

优化前(方案一)的查询方式如下

public MedicalHospital selectHospitalById(String id) {
MedicalHospital medicalHospital = medicalHospitalMapper.selectHospitalById(id);
List<MedicalHospitalPicture> medicalHospitalPictures = medicalHospitalPictureMapper.getMedicalHospitalPictureByHospitalId(medicalHospital.getId());
medicalHospital.setMedicalHospitalPictures(medicalHospitalPictures);
List<MedicalField> medicalFields = medicalHospitalMapper.selectMedicalFieldsByDoctorId(medicalHospital.getId());
medicalHospital.setFields(medicalFields);
return medicalHospital;
}


该种查询方式会执行三次sql,分别为:

1.查询出医馆(单表查询)

2.根据医馆id查图片(关联查询)

3.根据医馆id查医馆领域(关联查询)

以上方式有点类似与mybatis自带的collection中的select语句

优化后(方案二)的查询方式如下

public MedicalHospital selectHospitalById(String id) {
MedicalHospital medicalHospital = medicalHospitalMapper.selectHospitalById(id);
return medicalHospital;
}


<resultMap type="com.xczhihui.medical.hospital.model.MedicalHospital" id="MedicalHospitalBaseResult">
<id column="id" property="id" />
<id column="name" property="name" />
<id column="lal" property="lal" />
<id column="description" property="description" />
<id column="tel" property="tel" />
<id column="email" property="email" />
<id column="province" property="province" />
<id column="city" property="city" />
<id column="detailed_address" property="detailedAddress" />
<id column="score" property="score" />
<id column="authentication" property="authentication" />
</resultMap>


<resultMap type="com.xczhihui.medical.hospital.model.MedicalHospital" id="MedicalHospitalResult" extends="MedicalHospitalBaseResult">
<collection property="medicalHospitalPictures" ofType="com.xczhihui.medical.hospital.model.MedicalHospitalPicture">
<id column="picture" property="picture"/>
</collection>
<collection property="fields" ofType="com.xczhihui.medical.field.model.MedicalField">
<id column="fieldName" property="name"/>
</collection>
</resultMap>


<select id="selectHospitalById"  resultMap="MedicalHospitalResult">
SELECT
mh.id,
mh.name,
mh.lal,
mh.description,
mh.tel,
mh.email,
mh.province,
mh.city,
mh.detailed_address,
mh.score,
mh.authentication,
mh.recommend,
mhp.`picture`,
mf.`name` fieldName
FROM
medical_hospital mh LEFT JOIN `medical_hospital_picture` mhp ON mh.`id`=mhp.`hospital_id`
LEFT JOIN `medical_hospital_field` mhf ON mh.id = mhf.`hospital_id`
LEFT JOIN `me
4000
dical_field` mf ON mf.`id`=mhf.`field_id`
WHERE mh.deleted = 0
AND mh.status = 1  and  mh.id = #{id}
</select>


通过以上方式只需执行一个sql语句

以上两个方案的效率对比如下



目前表中数据量较少,当数据量上来之后,效率的差距还是值得优化的

另外,还有一个多对多的查询优化,简单描述下

场景二:多对多分页查询

涉及表:医馆表,图片表,医馆图片关系表

查询结果:一个列表含多个医馆对象,医馆对象里有一个含多个图片的集合

这种情况下,直接使用常用的单表分页比如pagehelper就会有问题了。

可以采用单表查出分页中的每页数据id,再通过数据id反查出所有数据的方式来实现多对多查询的分页联表查询

若采用类似mybatis自带的collection中的select语句方式,需要执行1(查出医馆列表)+n(查出每个医馆对应的所有图片)+n(查出每个医馆对应的所有领域)次sql(n为医馆数量)

而采用多表联查,只需执行1(查出医馆id列表)+1(查出医馆id列表对应的医馆列表信息)

这一场景的优化,对效率的影响也是不小的

在编码时,一定要注意接口的执行效率啊,不然遇到大数据量的功能时,就容易出问题了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息