先说明下业务查询主要字段(id,org_code,org_name,org_count其中org_count为计算统计出的数量)按数量前10条倒序排列首先考虑到用分页输出来控制效率
先贴上语句
SELECT t.ID,t.ORG_CODE,t.ORG_NAME,t.ORG_COUNT from
(SELECT ROWNUM RN ,A.ID,A.ORG_CODE,A.ORG_NAME,A.ORG_COUNT FROM
(SELECT c.ID,c.ORG_CODE,c.ORG_NAME,
(SELECT count(ID) from llt_report b where b.SEND_ORG_ID=c.ID) as ORG_COUNT from Llt_Org_Info c order by ORG_COUNT desc)
A WHERE ROWNUM <=10) t WHERE RN >0
因为oracle 中不支持top 关键字,分页只能靠rownum 来控制条数来显示,但最内层查询时已经把所有结果都扫描一遍
SELECT c.ID,c.ORG_CODE,c.ORG_NAME,
(SELECT count(ID) from llt_report b where b.SEND_ORG_ID=c.ID) as ORG_COUNT from Llt_Org_Info c order by ORG_COUNT desc
在用分页控制时就是对所有查询结果分页 并没有只查10条然后对这10条排序(也就是说分页并没有起到主要作用)
如果在查询中用ROWNUM 控制住条数但结果又不对
SELECT c.ID,c.ORG_CODE,c.ORG_NAME,
(SELECT count(ID) from llt_report b where b.SEND_ORG_ID=c.ID) as ORG_COUNT from Llt_Org_Info c
where rownum<=10 order by ORG_COUNT desc
经过反复测试发现问题主要集中在order by 排序后效率明显下降(说明查询时oracle先对表统一查询一遍然后又排序重执行一遍)!!(但排序必须保留)
首先oracle中感觉分页太繁琐,不断对层层结果集进程操作,频繁使用select查询 增加对表的操作次数降低了查询效率
10条查询耗时约1.4秒
那么Oracle中如何操作统计的字段排序
优化的几点建议:
1健壮的sql不要依赖数据进行条件过滤,要根据表的初衷设计来进行过滤条件
2要选好基础表,(基础表标准:信息涵盖全,数据量尽可能小 好比雪花型设计中的中心)
现在考虑直接筛选出所需字段,组成结果集
--优化后
select t.send_org_id,
(select a.org_code from llt_org_info a where a.id=t.send_org_id) as org_code,
(select a.org_name from llt_org_info a where a.id=t.send_org_id) as org_name,
count(t.send_org_id) as count_send_org_id ----统计数量的字段
from llt_report t
where t.send_org_id in (select id from llt_org_info) --过滤非所需信息
group by t.send_org_id order by count_send_org_id desc
耗时大约0.09秒
效率有了质的改变
总结:oracle中排序不建议用oracle中提供的ROWNUM分页,因为ROWNUM只能对查询的所有结果在过滤,并没在查询中控制数量 ,建议直接筛选字段排序不仅减少了SELECT的频繁使用,也使语句结果更加明朗!