优化自己的sql

优化自己的sql

第一次写一个viewsql跑了10多秒,无法忍受。最后优化到0.5秒左右。这里讲一下plsql中优化冗长sql的步骤方法。

 

1.       F5调出sql的执行计划。

2.       观察,计划中对哪些表进行了全表检索(TABLE ACCESS FULL),那些执行索引搜索(INDEX SCAN)的不用管。

3.       列出计划中全表检索的表,数一下每个表有多少数据:

Select count(1) from TABLE

4.       找出数据很多的表(一般万行以上),这些表数据多,又被全表检索,所以一定很慢。我们的主要工作就是围绕这几张表进行啦。

5.       整理sql,将select子句中,同表的字段写在一起,这样方便观察,例如

Select  pr.po_release_id,

 pr.release_num AS release_num,

 pr.revision_num AS release_vision_num,

 

 poh.vendor_id AS vendor_id_c,

 poh.vendor_site_id AS vendor_site_id_c,

 poh.po_header_id,

 poh.segment1 AS order_number,

 poh.revision_num AS item_revision,

 poh.creation_date AS creation_date,

 poh.vendor_contact_id AS contact_id,

 mc.concatenated_segments,

 mc.concatenated_segments AS category_name  from  … mc ,poh,pr……

WHERE pll.po_line_id = pol.po_line_id

   AND pll.po_release_id = pr.po_release_id(+)

   AND pol.po_header_id = poh.po_header_id

   AND fsp.org_id = pol.org_id

   AND mc.category_id(+) = pol.category_id

   AND msi.inventory_item_id(+) = pol.item_id

     

   AND poh.org_id = hou.organization_id

     

   AND pll.line_location_id = hvc.line_location_id(+)

     

   AND fsp.inventory_organization_id = nvl(msi.organization_id, fsp.inventory_organization_id)

     

   AND ood.organization_id(+) = pll.ship_to_organization_id

   AND hla.LANGUAGE(+) = sys_context('USERENV', 'LANG')

   AND hla.location_id(+) = pll.ship_to_location_id

     

 

 

6.       找出步骤4找出的表,假设为mcpoh两张表。观察其在select子句和中出现的次数。较少出现的表,即我们对这张表只是利用到它的个别字段,为此在from子句中多关联一张表是很不划算的事,因为多关联了一张表,sql执行过程将大大减缓。我们对这种情况的处理方法是:专门写一个function,从表中取所用的字段值。

 

比如这里,我们看到mc表在select子句中只出现了两次(上面代码红色部分),我们为了这两个字段又关联了一张很庞大的表,实在很不划算。我们要专门为这两个字段写一段function,将where子句中与mc相关的限制条件作为参数传入function。如上述代码绿色部分,最后我们的function类似这样:

Function get_catogory_name(p_catogory_id number);

 

7.       现在可以讲from子句和where子句中,与mc表相关的语句全部删掉了~!上述代码可以写成这样:

Select  pr.po_release_id,

 pr.release_num AS release_num,

 pr.revision_num AS release_vision_num,

 

 poh.vendor_id AS vendor_id_c,

 poh.vendor_site_id AS vendor_site_id_c,

 poh.po_header_id,

 poh.segment1 AS order_number,

 poh.revision_num AS item_revision,

 poh.creation_date AS creation_date,

 poh.vendor_contact_id AS contact_id,

 get_catogory_name(pol.category_id)

 get_catogory_name(pol.category_id) AS category_name  from …poh,pr…

WHERE pll.po_line_id = pol.po_line_id

   AND pll.po_release_id = pr.po_release_id(+)

   AND pol.po_header_id = poh.po_header_id

   AND fsp.org_id = pol.org_id

    AND msi.inventory_item_id(+) = pol.item_id

   AND poh.org_id = hou.organization_id

   AND pll.line_location_id = hvc.line_location_id(+)

   AND fsp.inventory_organization_id = nvl(msi.organization_id, fsp.inventory_organization_id)  

   AND ood.organization_id(+) = pll.ship_to_organization_id

   AND hla.LANGUAGE(+) = sys_context('USERENV', 'LANG')

   AND hla.location_id(+) = pll.ship_to_location_id

8.       现在我们为sql解决掉一张很大的并且无法使用索引检索的表,sql的执行速度将会得到比较明显的提升。

9.       对于select子句中出现次数较多的表,比如poh,虽然它也很大,执行计划中也无法用索引检索,但我们为它的每一个字段都写一个function是很麻烦的,这类表我们放在最后。如果速度还是无法忍受,也只好一个个写function了。要知道超过2秒的sql是客户无法忍受的~

10.    还有一些其它的优化方法,在执行计划中,如果看到有全表检索的表,要设法让它使用索引检索,同一张表,全表检索和索引检索的速度会差很多倍。

11.    这种写function的优化方式,只适合于优化where子句中使用了外连接的字段(AND mc.category_id(+) = pol.category_id),function查不到对应数据时可以返回null,起到了模拟外连接的作用。而外连接一般都是减缓sql执行速度的主要因素。

 

刚上项目,以上很多是前辈教的方法,有些东西自己也没有领会的很深刻,可能另外还有优化sql执行速度的好方法~希望大家不吝赐教~O(_)O~

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22414008/viewspace-617577/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22414008/viewspace-617577/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值