Oracle数据库数据恢复、性能优化

找回密码
注册
搜索
热搜: 活动 交友 discuz
发新帖

0

积分

1

好友

29

主题
1#
发表于 2013-1-16 09:30:03 | 查看: 4269| 回复: 5
原始语句
SELECT SUM(nvl(rcl.amount, 0)) amount, ooh.sold_to_org_id customer_id

FROM oe_order_headers_all   ooh,oe_order_lines_all     ool,  ra_interface_lines_all rcl

WHERE ooh.header_id = ool.header_id
           AND ool.open_flag = 'N'
           AND ool.line_id = rcl.interface_line_attribute6
           AND ooh.org_id in (103, 104)
  GROUP BY ooh.sold_to_org_id
执行计划
1         
2        --------------------------------------------------------------------------------------------
3        | Id  | Operation            | Name                         | Rows  | Bytes |TempSpc| Cost (%CPU)|
4        --------------------------------------------------------------------------------------------
5        |   0 | SELECT STATEMENT     |                        | 16480 |   627K|       | 46479   (2)|
6        |   1 |  HASH GROUP BY       |                        | 16480 |   627K|       | 46479   (2)|
7        |*  2 |   HASH JOIN          |                            |   148K|  5649K|  5360K| 46467   (2)|
8        |*  3 |    HASH JOIN         |                            |   148K|  3621K|  3480K| 38877   (2)|
9        |   4 |       TABLE ACCESS FULL| RA_INTERFACE_LINES_ALL |   148K|  1738K|       |  4411   (1)|
10        |*  5 |      TABLE ACCESS FULL| OE_ORDER_LINES_ALL     |   940K|    11M|       | 33164   (2)|
11        |*  6 |    TABLE ACCESS FULL | OE_ORDER_HEADERS_ALL   |   253K|  3459K|       |  7010   (1)|
12        --------------------------------------------------------------------------------------------
13         
14        Predicate Information (identified by operation id):
15        ---------------------------------------------------
16         
17           2 - access("OOH"."HEADER_ID"="OOL"."HEADER_ID")
18           3 - access("OOL"."LINE_ID"=TO_NUMBER("RCL"."INTERFACE_LINE_ATTRIBUTE6"))
19           5 - filter("OOL"."OPEN_FLAG"='N')
20           6 - filter("OOH"."ORG_ID"=103 OR "OOH"."ORG_ID"=104)
21         
22        Note
23        -----
24           - 'PLAN_TABLE' is old version
我的问题是:
关于第5步中的OPEN_FLAG"='N'造成了全表扫描,我的oe_order_lines_all     ool这张表约96万行数据,
SELECT COUNT(*) FROM (SELECT open_flag FROM oe_order_lines_all WHERE open_flag = 'N')返回94万行数据,确实是通过全表要比索引要好
但是问题是:这么一条设计百万行左右的语句要耗费半分钟左右才能返回结果,有没有办法通过修改语句或者访问路径能让他快一点的方法
注:
select * from v$version;
1        Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
2        PL/SQL Release 10.2.0.3.0 - Production
3        CORE        10.2.0.3.0        Production
4        TNS for IBM/AIX RISC System/6000: Version 10.2.0.3.0 - Productio
5        NLSRTL Version 10.2.0.3.0 - Production

2#
发表于 2013-1-16 10:00:05
补充一条OE_ORDER_HEADERS_ALL表共38万行左右数据
select count(*) from OE_ORDER_HEADERS_ALL   where org_id in (103, 104)返回24万行数据

回复 只看该作者 道具 举报

3#
发表于 2013-1-16 10:02:18
系统是OLAP还是OLTP系统?   如果是OLAP系统可以考虑给OPEN_FLAG加BITMAP INDEX

回复 只看该作者 道具 举报

4#
发表于 2013-1-16 10:07:14
wshxgxiaoli 发表于 2013-1-16 10:02
系统是OLAP还是OLTP系统?   如果是OLAP系统可以考虑给OPEN_FLAG加BITMAP INDEX

OLAP
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
对open_flag列加位图索引么?

回复 只看该作者 道具 举报

5#
发表于 2013-1-16 10:36:06
我刚刚对这个情况做了个小测试, 测试如下:
  1. SQL> create table testbit(id number(9));

  2. Table created.


  3. SQL> declare
  4.   2  i number(9);
  5.   3  begin
  6.   4     for i in 1..1000000 loop
  7.   5  insert into testbit values(i);
  8.   6  end loop;
  9.   7  end;
  10.   8  /

  11. PL/SQL procedure successfully completed.


  12. SQL> update testbit set id=9 where id<1000000;

  13. 999999 rows updated.

  14. SQL> commit;

  15. Commit complete.



  16. SQL> exec dbms_stats.gather_table_stats('SYS','TESTBIT');

  17. PL/SQL procedure successfully completed.

  18. SQL> set autotrace traceonly            
  19. SQL> create index idx_testbit on testbit(id);

  20. Index created.


  21. SQL> exec dbms_stats.gather_index_stats('SYS','IDX_TESTBIT');

  22. PL/SQL procedure successfully completed.

  23. SQL> set autotrace traceonly


  24. 10:25:43 SQL> select id from testbit where id=9;


  25. 999999 rows selected.


  26. Execution Plan
  27. ----------------------------------------------------------
  28. Plan hash value: 1663158793

  29. -----------------------------------------------------------------------------
  30. | Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
  31. -----------------------------------------------------------------------------
  32. |   0 | SELECT STATEMENT  |         |   500K|  1464K|   420   (2)| 00:00:06 |
  33. |*  1 |  TABLE ACCESS FULL| TESTBIT |   500K|  1464K|   420   (2)| 00:00:06 |
  34. -----------------------------------------------------------------------------

  35. Predicate Information (identified by operation id):
  36. ---------------------------------------------------

  37.    1 - filter("ID"=9)


  38. Statistics
  39. ----------------------------------------------------------
  40.           0  recursive calls
  41.           0  db block gets
  42.       68188  consistent gets
  43.           0  physical reads
  44.           0  redo size
  45.    17200437  bytes sent via SQL*Net to client
  46.      733850  bytes received via SQL*Net from client
  47.       66668  SQL*Net roundtrips to/from client
  48.           0  sorts (memory)
  49.           0  sorts (disk)
  50.      999999  rows processed

  51. 10:28:48 SQL> create bitmap index testbit_idx on testbit(id);

  52. Index created.

  53. 10:30:47 SQL> exec dbms_stats.gather_index_stats('SYS','TESTBIT_IDX');

  54. PL/SQL procedure successfully completed.

  55. 10:31:15 SQL> set autotrace traceonly
  56. 10:31:26 SQL> select id from testbit where id=9;

  57. 999999 rows selected.


  58. Execution Plan
  59. ----------------------------------------------------------
  60. Plan hash value: 3687339562

  61. --------------------------------------------------------------------------------
  62. -----------

  63. | Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)|
  64. Time     |

  65. --------------------------------------------------------------------------------
  66. -----------

  67. |   0 | SELECT STATEMENT            |             |   500K|  1464K|    11   (0)|
  68. 00:00:01 |

  69. |   1 |  BITMAP CONVERSION TO ROWIDS|             |   500K|  1464K|    11   (0)|
  70. 00:00:01 |

  71. |*  2 |   BITMAP INDEX SINGLE VALUE | TESTBIT_IDX |       |       |            |
  72.           |

  73. --------------------------------------------------------------------------------
  74. -----------


  75. Predicate Information (identified by operation id):
  76. ---------------------------------------------------

  77.    2 - access("ID"=9)


  78. Statistics
  79. ----------------------------------------------------------
  80.           8  recursive calls
  81.           0  db block gets
  82.          59  consistent gets
  83.           0  physical reads
  84.           0  redo size
  85.    17200437  bytes sent via SQL*Net to client
  86.      733850  bytes received via SQL*Net from client
  87.       66668  SQL*Net roundtrips to/from client
  88.           4  sorts (memory)
  89.           0  sorts (disk)
  90.      999999  rows processed
  91. 10:31:44 SQL>
复制代码
可以看到用BTREE和BITMAP的区别, BITMAP索引处理OLAP系统中的索引中重复值过多的情况相当有效!

回复 只看该作者 道具 举报

6#
发表于 2013-1-16 10:38:36
wshxgxiaoli 发表于 2013-1-16 10:36
我刚刚对这个情况做了个小测试, 测试如下:可以看到用BTREE和BITMAP的区别, BITMAP索引处理OLAP系统中的 ...

太感谢了,做的太透彻了

回复 只看该作者 道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|Archiver|Oracle数据库数据恢复、性能优化

GMT+8, 2024-11-16 06:48 , Processed in 0.051250 second(s), 20 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部
TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569