+ -
当前位置:首页 → 问答吧 → 头大,请大虾提供百万数据查询优化思路。

头大,请大虾提供百万数据查询优化思路。

时间:2008-04-29

来源:互联网

下面一个查询需要六十秒 ssinvoice 有30万条记录,ssfeedetail 有400万条记录,想问这样的数据量需要这么多时间正常不。如果要优化,可提达到的理想状态时多少,有什么优化思路。 


select * 
from ssinvoice iv, ssfeedetail f 
where f.ssfd_invoice_no = iv.ssiv_invoice_no 
and f.ssfd_biz_type_code = '3' 
AND f.ssfd_imp_exp_flag = 'E' 

AND f.ssfd_org_id = '86' 
AND f.ssfd_supplier_code = 'ESHA00001259' 
AND (f.ssfd_payment_flag != 'Y' OR f.ssfd_payment_flag IS NULL) 

AND (f.ssfd_wo_status = '2' OR f.ssfd_wo_status IS NULL) 

and iv.ssiv_entrust_no is null 



Execution Plan 
---------------------------------------------------------- 
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1311 Card=117 Bytes= 
70902) 

1 0 NESTED LOOPS (Cost=1311 Card=117 Bytes=70902) 
2 1 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF 'SSFEEDETAIL' (C 
ost=883 Card=214 Bytes=66126) 

3 2 INDEX (RANGE SCAN) OF 'IDX_SSFD_ORG_SUPPLIER' (NON-UNI 
QUE) (Cost=29 Card=5986) 

4 1 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF 'SSINVOICE' (Cos 
t=2 Card=1 Bytes=297) 

5 4 INDEX (UNIQUE SCAN) OF 'PK_SSINVOICE' (UNIQUE) (Cost=1 
Card=1) 





Statistics 
---------------------------------------------------------- 
71 recursive calls 
0 db block gets 
8131 consistent gets 
5533 physical reads 
0 redo size 
85181 bytes sent via SQL*Net to client 
404 bytes received via SQL*Net from client 
20 SQL*Net roundtrips to/from client 
0 sorts (memory) 
0 sorts (disk) 
285 rows processed

作者: jyplp   发布时间: 2008-04-29

对where 语句里面的字段建立索引。这个就不用说了。
然后我看到你很多判断里面用到了 is null你想办法换个写法,写成 is not null 这样会变得快很多的。为什么我就不知道了。我以前试过,时间相差很多。本来一个需要3秒的,变成is not null 就变成0.几秒了。我是这么写的 (when a is not null then 1 else 2 end)=2这样就能快很多
还有就是 如果该查询不需要很精确的话,你可以建立物化视图,定在每天晚上进行查询。就可以了。你的查询就查询这个物化视图就可以了

作者: ahua3515   发布时间: 2008-04-29

思路就是 尽量减少总的数据处理量和 提高单位时间的处理能力

你最后的结果只有285条,你的索引可能建得不合理,可以考虑复合索引,另外尝试下更改表的连接顺序 或者采用 hash join

作者: fjmingyang   发布时间: 2008-04-29

select * 这部分需要的字段还是应该列出来。
如果从某一表中所选出的字段都在这个表的索引中,那么可以减少一步table access by rowid来取得其他不相干的列。
建立索引的时候除了考虑where部分也要考虑到select子句选择了几个字段。

作者: doer_ljy   发布时间: 2008-04-29

顶你

作者: zhu_gx   发布时间: 2008-04-29

好。先谢谢各位,我试试,一会把测试结果贴出来。还有其他的办法,请各位不要客气啊。

作者: jyplp   发布时间: 2008-04-29

AND f.ssfd_org_id = '86'  
AND f.ssfd_supplier_code = 'ESHA00001259'  

ssfeedetail 上有这两个字段的索引。

作者: jyplp   发布时间: 2008-04-29

我觉得关键在两个
1,select * 估计是你这个慢的最大原因
2,建议建立索引,并放在专用的分区里
3,这个也比较关键
AND (f.ssfd_payment_flag != 'Y' OR f.ssfd_payment_flag IS NULL)  

AND (f.ssfd_wo_status = '2' OR f.ssfd_wo_status IS NULL)  

这两句有OR的条件应该放在WHERE后的第一和第二项首先判断,这样会加快很多

作者: super_ssy   发布时间: 2008-04-29

select * 
from ssinvoice iv, ssfeedetail f 
where f.ssfd_invoice_no = iv.ssiv_invoice_no 
and f.ssfd_biz_type_code = '3' 
AND f.ssfd_imp_exp_flag = 'E' 
AND f.ssfd_org_id = '86' 
AND f.ssfd_supplier_code = 'ESHA00001259' 
AND (f.ssfd_payment_flag != 'Y' OR f.ssfd_payment_flag IS NULL) 
AND (f.ssfd_wo_status = '2' OR f.ssfd_wo_status IS NULL)  

看你的查询语句中对于ssfeedetail表只是和ssinvoice 进行关联,而在下面都是对f表的过滤。
你看能不能把f先筛出来,然后再与iv关联,这样会快点吧。
另外,你的表iv与f中的ssfd_invoice_no 与ssiv_invoice_no这两个字段是否建立了索引

作者: zxf_feng   发布时间: 2008-04-29

再顶一下

作者: zhu_gx   发布时间: 2008-04-29

1.建临时表
create table t as select * from ssfeedetail f  
where f.ssfd_biz_type_code = '3'  
AND f.ssfd_imp_exp_flag = 'E'
AND f.ssfd_org_id = '86'  
AND f.ssfd_supplier_code = 'ESHA00001259'  
AND (f.ssfd_payment_flag != 'Y' OR f.ssfd_payment_flag IS NULL)
AND (f.ssfd_wo_status = '2' OR f.ssfd_wo_status IS NULL);
2.查询  
select *  
from ssinvoice iv,t f
where f.ssfd_invoice_no = iv.ssiv_invoice_no  
and iv.ssiv_entrust_no is null ;
分两步试试看会不会快点

作者: wffffc   发布时间: 2008-04-29

看着大家的讨论,学了很多

作者: jin_ok   发布时间: 2008-04-29

大表的查询,尽量少于表关联查询,一张表一张表的查询,虽然次数会多点,但是效率会高很多

作者: fenglibing   发布时间: 2011-11-15

学习了,再顶一下

作者: snowboy8886   发布时间: 2011-11-15

热门下载

更多