SELECT `t1`.`id` AS `id`, `t1`.`projectcode` AS `project_id`, `t1`.`projectname` AS `project_name`, `t1`.`projecttype` AS `projecttype`, `t1`.`projectstatus` AS `projectstatus`, COALESCE ( `t2`.`jlcount`, 0 ) AS `Processdata`, COALESCE ( `t3`.`jlcount`, 0 ) AS `safe`, COALESCE ( `t4`.`jlcount`, 0 ) AS `owner`, `t1`.`del_flag` AS `del_flag` FROM ((( `ht_engineer_schema`.`ht_project` `t1` LEFT JOIN ( SELECT `ht_engineer_schema`.`ht_project_item_control`.`project_id` AS `project_id`, count( 1 ) AS `jlcount` FROM `ht_engineer_schema`.`ht_project_item_control` WHERE (( `ht_engineer_schema`.`ht_project_item_control`.`control_type` = '1' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`flow_id` = 'kgzl' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`del_flag` = '0' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`control_status` = '2' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`flow_status` = '2' )) GROUP BY `ht_engineer_schema`.`ht_project_item_control`.`project_id` ) `t2` ON (( `t1`.`id` = `t2`.`project_id` ))) LEFT JOIN ( SELECT `ht_engineer_schema`.`ht_project_item_control`.`project_id` AS `project_id`, count( 1 ) AS `jlcount` FROM `ht_engineer_schema`.`ht_project_item_control` WHERE (( `ht_engineer_schema`.`ht_project_item_control`.`control_type` = '1' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`flow_id` = 'safe' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`del_flag` = '0' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`control_status` = '2' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`flow_status` = '2' )) GROUP BY `ht_engineer_schema`.`ht_project_item_control`.`project_id` ) `t3` ON (( `t1`.`id` = `t3`.`project_id` ))) LEFT JOIN ( SELECT `ht_engineer_schema`.`ht_project_item_control`.`project_id` AS `project_id`, count( 1 ) AS `jlcount` FROM `ht_engineer_schema`.`ht_project_item_control` WHERE (( `ht_engineer_schema`.`ht_project_item_control`.`control_type` = '1' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`flow_id` = 'jfzl' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`del_flag` = '0' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`control_status` = '2' ) AND ( `ht_engineer_schema`.`ht_project_item_control`.`flow_status` = '2' )) GROUP BY `ht_engineer_schema`.`ht_project_item_control`.`project_id` ) `t4` ON (( `t1`.`id` = `t4`.`project_id` ))) WHERE (( `t1`.`del_flag` = '0' ) AND ( `t1`.`mobiledisplay` = 'Y' )) 这个sql还可以优化吗
时间: 2025-07-05 10:08:42 浏览: 6
这个SQL查询可以通过条件聚合进一步优化,将三个LEFT JOIN子查询合并为一个。以下是优化方案:
### 优化方案(条件聚合)
```sql
SELECT
t1.id,
t1.projectcode AS project_id,
t1.projectname AS project_name,
t1.projecttype,
t1.projectstatus,
t1.del_flag,
-- 使用条件聚合替代多个JOIN
COUNT(CASE WHEN t.control_type = '1' AND t.flow_id = 'kgzl'
AND t.del_flag = '0' AND t.control_status = '2' AND t.flow_status = '2' THEN 1 END) AS Processdata,
COUNT(CASE WHEN t.control_type = '1' AND t.flow_id = 'safe'
AND t.del_flag = '0' AND t.control_status = '2' AND t.flow_status = '2' THEN 1 END) AS safe,
COUNT(CASE WHEN t.control_type = '1' AND t.flow_id = 'jfzl'
AND t.del_flag = '0' AND t.control_status = '2' AND t.flow_status = '2' THEN 1 END) AS owner
FROM
ht_engineer_schema.ht_project t1
LEFT JOIN
ht_engineer_schema.ht_project_item_control t ON t1.id = t.project_id
WHERE
t1.del_flag = '0'
AND t1.mobiledisplay = 'Y'
GROUP BY
t1.id, t1.projectcode, t1.projectname, t1.projecttype, t1.projectstatus, t1.del_flag;
```
### 优化说明:
1. **关键改进**:
- 将3个LEFT JOIN子查询合并为1个LEFT JOIN + 条件聚合
- 使用COUNT(CASE WHEN...)替代COALESCE(COUNT,0)实现条件计数
- 移除了冗余的表名前缀(`ht_engineer_schema`.`ht_project_item_control`)
2. **性能优势**:
- 原始查询需要扫描`ht_project_item_control`表3次
- 优化后只需扫描1次,减少I/O操作
- 减少了临时表的创建和连接操作
3. **索引建议**:
```sql
-- 确保有以下复合索引(如果尚未创建)
CREATE INDEX IF NOT EXISTS idx_pic_project_control
ON ht_project_item_control(project_id, control_type, flow_id, del_flag, control_status, flow_status);
CREATE INDEX IF NOT EXISTS idx_project_query
ON ht_project(del_flag, mobiledisplay, id);
```
### 进一步优化建议:
1. **使用SUM替代COUNT**(如果NULL值处理更高效):
```sql
SELECT
t1.id,
-- 其他字段...
SUM(CASE WHEN t.control_type = '1' AND t.flow_id = 'kgzl'
AND t.del_flag = '0' AND t.control_status = '2' AND t.flow_status = '2' THEN 1 ELSE 0 END) AS Processdata,
-- 其他统计字段...
```
2. **添加查询提示**(如果数据库支持):
```sql
SELECT /*+ LEADING(t1) USE_NL(t) */
t1.id,
-- 其他字段...
```
3. **考虑物化视图**(如果查询频繁且数据不常变化):
```sql
CREATE MATERIALIZED VIEW mv_project_stats AS
SELECT
t1.id,
-- 统计字段...
FROM
ht_project t1
LEFT JOIN ht_project_item_control t ON t1.id = t.project_id
WHERE
t1.del_flag = '0' AND t1.mobiledisplay = 'Y'
GROUP BY
t1.id, t1.projectcode, t1.projectname, t1.projecttype, t1.projectstatus, t1.del_flag;
```
### 优化效果验证:
建议使用EXPLAIN分析优化前后的执行计划,重点关注:
1. 扫描次数(rows字段)
2. 是否使用了正确的索引
3. 临时表使用情况
4. 排序操作
阅读全文
相关推荐










