select a.code as reportCode,b.id,f.NAME,b.title,b.CODE,to_char(b.START_DATE,'yyyy') as year,b.RGID,c.TITLE as groupName,count(e.VALUE) as dataNum
from T_R_MT_UREPORT a
right join (select * from T_R_MONITOR_TASK where is_del=0) b on a.mtid=b.id
left outer join (select * from T_R_MT_REPORT_GROUP where IS_DEL=0) c on b.RGID=c.ID
left outer join (select * from T_R_MT_RG_ITEM where IS_DEL=0 and TITLE in ('检测项目')) d on c.ID=d.RGID
left outer join (select * from T_R_MT_REPORT_DATA where IS_DEL=0) e on d.ID=e.RGIID and b.ID=e.MTID
left outer join (select * from T_B_ORGANIZATION where IS_DEL=0) f on b.OID=f.ID
where
a.IS_DEL=0
and b.VALID_STAGE >= 6
and c.IS_SUBMIT=1
and f.VALID_STAGE IN (8,9)
and e.CODE IN (
SELECT y.CODE FROM T_R_MT_RG_ITEM z
LEFT OUTER JOIN T_R_MT_REPORT_DATA y ON z.ID=y.RGIID
WHERE z.RGID=c.ID AND z.TITLE IN ('报告编号') AND y.VALUE = a.code and y.mtid=b.id
)
group by a.code,f.NAME,b.id,b.TITLE,b.CODE,to_char(b.START_DATE,'yyyy'),b.RGID,c.TITLE
having count(e.VALUE) > 0
order by dataNum desc
这个代码是你自己写的?干嘛要用这么多的子查询呢,我这里经常交互访问的元组创建了索引,你可以用exist代替in,效率更高很多,这些还得结合你具体的执行计划来看,有的时候不是光改代码逻辑就看得到明显性能提升
CREATE INDEX idx_T_R_MT_UREPORT_IS_DEL ON T_R_MT_UREPORT (IS_DEL);
CREATE INDEX idx_T_R_MONITOR_TASK_is_del ON T_R_MONITOR_TASK (is_del);
CREATE INDEX idx_T_R_MONITOR_TASK_VALID_STAGE ON T_R_MONITOR_TASK (VALID_STAGE);
CREATE INDEX idx_T_R_MT_REPORT_GROUP_IS_DEL ON T_R_MT_REPORT_GROUP (IS_DEL);
CREATE INDEX idx_T_R_MT_RG_ITEM_IS_DEL ON T_R_MT_RG_ITEM (IS_DEL);
CREATE INDEX idx_T_R_MT_RG_ITEM_TITLE ON T_R_MT_RG_ITEM (TITLE);
CREATE INDEX idx_T_R_MT_REPORT_DATA_IS_DEL ON T_R_MT_REPORT_DATA (IS_DEL);
CREATE INDEX idx_T_B_ORGANIZATION_IS_DEL ON T_B_ORGANIZATION (IS_DEL);
CREATE INDEX idx_T_B_ORGANIZATION_VALID_STAGE ON T_B_ORGANIZATION (VALID_STAGE);
CREATE INDEX idx_T_R_MONITOR_TASK_id_VALID_STAGE ON T_R_MONITOR_TASK (id, VALID_STAGE);
CREATE INDEX idx_T_R_MT_REPORT_GROUP_ID_IS_SUBMIT ON T_R_MT_REPORT_GROUP (ID, IS_SUBMIT);
CREATE INDEX idx_T_R_MT_RG_ITEM_RGID_TITLE_ID ON T_R_MT_RG_ITEM (RGID, TITLE, ID);
CREATE INDEX idx_T_R_MT_REPORT_DATA_RGIID_MTID ON T_R_MT_REPORT_DATA (RGIID, MTID);
CREATE INDEX idx_T_R_MT_UREPORT_code ON T_R_MT_UREPORT (code);
CREATE INDEX idx_T_R_MONITOR_TASK_id_title_START_DATE_RGID_CODE ON T_R_MONITOR_TASK (id, title, START_DATE, RGID, CODE);
CREATE INDEX idx_T_R_MT_REPORT_GROUP_ID_TITLE ON T_R_MT_REPORT_GROUP (ID, TITLE);
CREATE INDEX idx_T_B_ORGANIZATION_NAME ON T_B_ORGANIZATION (NAME);
问题点:查询数据较多,提高查询效率
分析思路:一般提高查询效率的方法,
①建立常用的索引(推荐)立竿见晓的提升
②查询语句优化,尽量减少跨表的join操作,大表join小表,搞不好就是扫描全表,这种情况,还是试试建立一个临时表,在临时表的基础上进行查询.
③数据库表结构优化,这个类似②的操作,就是改动的动作更大.
可以参考一下
SELECT
a.code AS reportCode,
b.id,
f.NAME,
b.title,
b.CODE,
TO_CHAR(b.START_DATE, 'yyyy') AS year,
b.RGID,
c.TITLE AS groupName,
COUNT(e.VALUE) AS dataNum
FROM
T_R_MT_UREPORT a
JOIN T_R_MONITOR_TASK b ON a.mtid = b.id AND b.is_del = 0
LEFT JOIN T_R_MT_REPORT_GROUP c ON b.RGID = c.ID AND c.IS_DEL = 0
LEFT JOIN T_R_MT_RG_ITEM d ON c.ID = d.RGID AND d.IS_DEL = 0 AND d.TITLE = '检测项目'
LEFT JOIN T_R_MT_REPORT_DATA e ON d.ID = e.RGIID AND b.ID = e.MTID AND e.IS_DEL = 0
LEFT JOIN T_B_ORGANIZATION f ON b.OID = f.ID AND f.IS_DEL = 0
WHERE
a.IS_DEL = 0
AND b.VALID_STAGE >= 6
AND c.IS_SUBMIT = 1
AND f.VALID_STAGE IN (8, 9)
AND EXISTS (
SELECT 1
FROM
T_R_MT_RG_ITEM z
LEFT JOIN T_R_MT_REPORT_DATA y ON z.ID = y.RGIID AND y.IS_DEL = 0
WHERE
z.RGID = c.ID
AND z.TITLE = '报告编号'
AND y.VALUE = a.code
AND y.mtid = b.id
)
GROUP BY
a.code,
f.NAME,
b.id,
b.TITLE,
b.CODE,
TO_CHAR(b.START_DATE, 'yyyy'),
b.RGID,
c.TITLE
HAVING
COUNT(e.VALUE) > 0
ORDER BY
dataNum DESC;
哥们,你得先把你的sql拆解一下,我先说下我的思路哈
1.把多次嵌套查询的sql单独执行,检查执行结果。如:SELECT * FROMT_R_MT_RG_ITEM WHERE IS_DEL = 0 AND TITLE IN ( '检测项目', SELECT * FROM T_R_MT_REPORT_DATA WHERE IS_DEL = 0,SELECT * FROM T_B_ORGANIZATION WHERE IS_DEL = 0 )等,这种sql如果执行慢,那后续肯定慢,没得跑
2.在确定这几个sql执行都没问题的情况下,检查是否执行索引,这个可以在navicat中查看
首先你的子查询太多了,优化下,explain看下你这条sql的执行计划,其次就是如果联查的话加上索引
看下有没有办法减少left join的次数,然后left join的关联字段添加索引,where后面的字段增加索引试试。
你这sql复杂度不高,我把你每个selec * 里的条件加到where里去,这样全量查询一次,你试试
select a.code as reportCode,b.id,f.NAME,b.title,b.CODE,to_char(b.START_DATE,'yyyy') as year,b.RGID,c.TITLE as groupName,count(e.VALUE) as dataNum
from T_R_MT_UREPORT a
right join T_R_MONITOR_TASK b on a.mtid=b.id
left outer join T_R_MT_REPORT_GROUP c on b.RGID=c.ID
left outer join T_R_MT_RG_ITEM d on c.ID=d.RGID
left outer join T_R_MT_REPORT_DATA e on d.ID=e.RGIID and b.ID=e.MTID
left outer join T_B_ORGANIZATION f on b.OID=f.ID
where
a.IS_DEL=0 and b.IS_DEL=0 and c.IS_DEL=0
and d.IS_DEL=0 and TITLE in ('检测项目') and e.IS_DEL=0
and f.IS_DEL=0
and b.VALID_STAGE >= 6
and c.IS_SUBMIT=1
and f.VALID_STAGE IN (8,9)
and e.CODE IN (
SELECT y.CODE FROM T_R_MT_RG_ITEM z
LEFT OUTER JOIN T_R_MT_REPORT_DATA y ON z.ID=y.RGIID
WHERE z.RGID=c.ID AND z.TITLE IN ('报告编号') AND y.VALUE = a.code and y.mtid=b.id
)
group by a.code,f.NAME,b.id,b.TITLE,b.CODE,to_char(b.START_DATE,'yyyy'),b.RGID,c.TITLE
having count(e.VALUE) > 0
order by dataNum desc
你的查询有很多连接查询,可能需要考虑重新规划下你的查询语句。前面说的建立索引,效果应该不大。还是应该从sql语句下手。不必统计所有数据,可以使用LIMIT和OFFSET子句来分页查询。通过限制返回的行数,可以减少查询的数据量。如果表非常大,可以考虑使用数据库分区来将表分成较小的部分。每个分区可以单独查询,从而提高查询性能。
创建索引可以提高速度
建索引
帮你优化了一下 有帮助的话 采纳一下
SELECT
a.code AS reportCode,
b.id,
f.NAME,
b.title,
b.CODE,
b.START_DATE AS year,
b.RGID,
c.TITLE AS groupName,
COUNT(e.VALUE) AS dataNum
FROM T_R_MT_UREPORT a
LEFT JOIN T_R_MONITOR_TASK b ON a.mtid = b.id
LEFT JOIN T_R_MT_REPORT_GROUP c ON b.RGID = c.ID
LEFT JOIN T_R_MT_RG_ITEM d ON c.ID = d.RGID
LEFT JOIN T_R_MT_REPORT_DATA e ON d.ID = e.RGIID AND b.ID = e.MTID
LEFT JOIN T_B_ORGANIZATION f ON b.OID = f.ID
WHERE
a.IS_DEL = 0
AND b.VALID_STAGE >= 6
AND c.IS_SUBMIT = 1
AND f.VALID_STAGE IN (8,9)
AND e.CODE IN (
SELECT y.CODE
FROM T_R_MT_RG_ITEM z
LEFT JOIN T_R_MT_REPORT_DATA y ON z.ID = y.RGIID
WHERE z.RGID = c.ID AND z.TITLE IN ('报告编号') AND y.VALUE = a.code and y.mtid = b.id
)
GROUP BY
a.code, b.id, f.NAME, b.title, b.CODE, b.START_DATE, b.RGID, c.TITLE
HAVING
COUNT(e.VALUE) > 0
ORDER BY
dataNum DESC
参考newbing
当 SQL 查询的结果集过大时,可以尝试以下几种方法来提高查询速度:
索引优化:确保相关列上有适当的索引。通过创建索引,可以加快查询的速度。你可以在经常用于过滤、连接或排序的列上创建索引。在这个查询中,你可以考虑在 T_R_MONITOR_TASK
表的 is_del
列上创建索引,以及在 T_R_MT_REPORT_GROUP
表的 IS_DEL
列上创建索引。
子查询优化:尽量减少子查询的使用。子查询在某些情况下可能会导致性能下降。你可以尝试将子查询转换为连接或其他更高效的方式来处理。
数据库优化:确保数据库的配置和参数设置合理。例如,你可以调整数据库的缓冲区大小、并发连接数等参数,以提高查询性能。
数据库分区:如果数据量非常大,你可以考虑对表进行分区。分区可以将表的数据划分为多个逻辑部分,并将其存储在不同的物理位置上,从而提高查询性能。
数据库缓存:使用适当的缓存机制来减少对数据库的访问次数。例如,你可以使用缓存来存储频繁查询的结果,以减少对数据库的查询操作。
数据库性能监控:定期监控数据库的性能,并识别潜在的性能瓶颈。通过监控和优化数据库的性能,可以提高查询的速度。
请注意,以上方法可能需要根据你的具体情况进行调整和实施。如果你不确定如何进行优化,建议咨询数据库管理员或专业人士的帮助。