我正在尝试使用在多个表上留下连接的查询来获取数据。该查询返回 4132 行,持续时间为 4.55 秒,在
mysql workbench
中提取需要 31.30 秒。我什至尝试从 php
执行它,但这需要相同的时间。
SELECT
aa.bams_id AS chassis_bams_id, aa.hostname AS chassis_hostname,
aa.rack_number AS chassis_rack, aa.serial_number AS chassis_serial, aa.site_id AS chassis_site_id,
cb.bay_number, cb.bsn AS serial_number_in_bay,
CASE
WHEN a_a.bams_id IS NULL THEN 'Unknown'
ELSE a_a.bams_id
END AS blade_bams_id,
a_a.hostname AS blade_hostname, a_s.description AS blade_status, a_a.manufacturer AS blade_manufacturer, a_a.model AS blade_model,
a_a.bookable_unit_id AS blade_bookable_unit_id, a_a.rack_number AS blade_rack_number, a_a.manufactured_date AS blade_manufactured_date,
a_a.support_expired_date AS blade_support_expired_date, a_a.site_id AS blade_site_id
FROM all_assets aa
LEFT JOIN manufacturer_model mm ON aa.manufacturer = mm.manufacturer AND aa.model = mm.model
LEFT JOIN chassis_bays cb ON aa.bams_id = cb.chassis_bams_id
LEFT JOIN all_assets a_a ON cb.bsn = a_a.serial_number
LEFT JOIN asset_status a_s ON a_a.status=a_s.status
WHERE mm.hardware_type = 'chassis';
这些是所使用的表的定义:
EXPLAIN
的输出:
查询获取每个机箱内每个刀片的数据。 在其他系统上执行相同的查询,只需要5秒即可获取结果。
如何优化此查询?
更新(已解决)
按照专家的建议添加了此处的索引。 下面是添加索引后的执行计划。
创建索引,非索引读取比索引读取慢。
要准确确定导致性能下降的原因,最好的工具 就是使用“查询计划分析器”:
看这里: mySql性能讲解
尝试在将要发生的最明显的读取上创建索引。查看在加入时发挥作用的字段以及 where 子句。如果您在这些字段上有索引,如果发生非索引读取,您的性能应该会提高。
如果这仍然是一个问题,最好看看 mySQL 如何获取数据, 有时会重组您的数据,甚至可能改变您的排队方式 可以给你更好的结果。
例如。创建索引:aa.manufacturer_model、aa.manufacturer、aa.model 和 mm.hardware_type
我有一个
user
s 表,与其他表有很多关系:21 LEFT JOIN
s。
该查询不仅花费了很长时间,而且还导致我的 NodeJS 服务器崩溃,并出现“JS 堆内存不足”...
我的解决方案是将一些
left join
转换为使用 sub query
和 JSON_ARRAYAGG
的
GROUP BY
user
的数据。sub query
和 group by
(如果适合您)的 JSON_ARRAYAGG
。 (当然还有 JSON.parse()。(JS))我有多对多的关系。这意味着 2
LEFT JOIN
s
上一篇:
LEFT JOIN `therapists_treatment_qualifications` `therapist_treatmentQualifications` ON `therapist_treatmentQualifications`.`user_id` = `therapist`.`id`
LEFT JOIN `treatment_qualification` `treatmentQualifications` ON `treatmentQualifications`.`id` = `therapist_treatmentQualifications`.`treatment_qualification_id`
解决方案:
// "query 1":
const therapist = await this.therapistRepository.createQueryBuilder('therapist');
.leftJoinAndSelect('therapist.languages', 'languages')
.where('therapist.id = :therapistId', { therapistId })
.getOne();
// "query 2":
const therapist_moreFieldsStringified = await this.therapistRepository.createQueryBuilder('therapist')
.select([]) // otherwise will select therapist table columns
.addSelect(qb => (
qb.select(`JSON_ARRAYAGG(JSON_OBJECT("name", treatmentQualifications.name, "id", treatmentQualifications.id))`, "treatment_qualifications")
.from("therapists_treatment_qualifications", "therapist_treatmentQualifications")
.innerJoin("treatment_qualification", "treatmentQualifications", "treatmentQualifications.id = therapist_treatmentQualifications.treatment_qualification_id")
.where("therapist_treatmentQualifications.user_id = therapist.id")
.groupBy("therapist_treatmentQualifications.user_id")
), "treatmentQualifications")
... // more .addSelect(..^same as above^..) if needed
.getRawOne();
// add fields of "query 2" to "query 1"`s therapist
for (const fieldName in therapist_moreFieldsStringified) {
const stringifiedValue = therapist_moreFieldsStringified[fieldName]
therapist[fieldName] = JSON.parse(stringifiedValue);
}