我在这里不会介绍OLTP和OLAP的概念,这些入行的DBA都是必懂的。今天的话题是绑定变量为什么适合在OLTP系统而不宜于OLAP系统。从某种角度上我们可以这样看待OLTP和OLAP系统,OLTP系统小查询多而OLAP系统基本都是大查询,而它们致命的区别就是执行时间上(结果集有很大的区别),所以我们也可以说OLTP系统适合短查询、OLAP系统则适合长查询。不管怎样,在OLTP系统,我们需要注重小查询的快速执行,为此而能够做的优化操作之一就是提高SQL命中率、使用索引(索引访问小结果集),而绑定变量特性恰恰能够提高SQL的重复使用频率,减少反复解析次数,进而极大节省系统资源的消耗。在OLAP系统,报表类查询里经常有聚合排序操作,一般都是庞大的结果集,在这里解析所耗的系统资源基本可以忽略,为达到加快查询的优化目的,我们要注重执行计划的正确选择,而绑定变量的使用很可能让CBO选择错误的执行计划,故不适合使用。




下面通过示例查看绑定变量影响OLTP和OLAP系统的效果。






下面简要介绍OLAP系统下的影响:


-- 我有一张大表

luocs@MAA> select count(*) from tt1;


COUNT(*)

----------

   338752


luocs@MAA> select index_name, index_type, status from user_indexes where table_name='TT1';


INDEX_NAME      INDEX_TYPE      STATUS

--------------- --------------- ----------------

INX_TT1_OWNER   BITMAP          VALID


luocs@MAA> select COLUMN_NAME, NUM_DISTINCT from user_tab_cols where table_name='TT1';


COLUMN_NAME                                                  NUM_DISTINCT

------------------------------------------------------------ ------------

OWNER                                                                  15

OBJECT_NAME                                                         16272

SUBOBJECT_NAME                                                        333

OBJECT_ID                                                           21204

DATA_OBJECT_ID                                                       6221

OBJECT_TYPE                                                            36

CREATED                                                               855

LAST_DDL_TIME                                                         907

TIMESTAMP                                                             935

STATUS                                                                  1

TEMPORARY                                                               2

GENERATED                                                               2

SECONDARY                                                               2

NAMESPACE                                                              15

EDITION_NAME                                                            0


-- 查看OWNER为SYS和SYSTEM的记录数

luocs@MAA> select count(*) from tt1 where owner='SYS';


COUNT(*)

----------

   152960


luocs@MAA> select count(*) from tt1 where owner='SYSTEM';


COUNT(*)

----------

     8208


-- 查看执行计划

luocs@MAA> explain plan for select count(*) from tt1 where owner='SYS';


Explained.


luocs@MAA> select * from table(dbms_xplan.display);


PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------------------------

Plan hash value: 945689350


---------------------------------------------------------------------------------------------

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

---------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |               |     1 |     7 |     7   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE             |               |     1 |     7 |            |          |

|   2 |   BITMAP CONVERSION COUNT   |               |   153K|  1047K|     7   (0)| 00:00:01 |

|*  3 |    BITMAP INDEX SINGLE VALUE| INX_TT1_OWNER |       |       |            |          |

---------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):

---------------------------------------------------


3 - access("OWNER"='SYS')


15 rows selected.


luocs@MAA> explain plan for select count(*) from tt1 where owner='SYSTEM';


Explained.


luocs@MAA> select * from table(dbms_xplan.display);


PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------------------------

Plan hash value: 945689350


---------------------------------------------------------------------------------------------

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

---------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |               |     1 |     7 |     1   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE             |               |     1 |     7 |            |          |

|   2 |   BITMAP CONVERSION COUNT   |               |  8390 | 58730 |     1   (0)| 00:00:01 |

|*  3 |    BITMAP INDEX SINGLE VALUE| INX_TT1_OWNER |       |       |            |          |

---------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):

---------------------------------------------------


3 - access("OWNER"='SYSTEM')


15 rows selected.


-- 通过10046事件查看使用绑定变量后的结果


luocs@MAA> alter session set events '10046 trace name context forever, level 4';


Session altered.


luocs@MAA> variable l varchar2(10)

luocs@MAA> exec :l:='SYS'


PL/SQL procedure successfully completed.


luocs@MAA> select count(*) from tt1 where owner=:l;


COUNT(*)

----------

   152960


luocs@MAA> exec :l:='SYSTEM'


PL/SQL procedure successfully completed.


luocs@MAA> select count(*) from tt1 where owner=:l;


COUNT(*)

----------

     8208


luocs@MAA> alter session set events '10046 trace name context off';


Session altered.


luocs@MAA> select value from v$diag_info where name = 'Default Trace File';


VALUE

----------------------------------------------------------------------------------------------------

/u01/app/oracle/diag/rdbms/maa/maa/trace/maa_ora_9081.trc


-- 格式化下

[oracle@maa3 ~]$ tkprof /u01/app/oracle/diag/rdbms/maa/maa/trace/maa_ora_9081.trc luocs.txt aggregate=no


-- trace部分内容

SQL ID: 6yw9t0j4w7hvh Plan Hash: 0


BEGIN :l:='SYS'; END;


call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute      1      0.00       0.00          0          0          0           1

Fetch        0      0.00       0.00          0          0          0           0

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total        2      0.00       0.00          0          0          0           1


Misses in library cache during parse: 0

Optimizer mode: ALL_ROWS

Parsing user id: 51

********************************************************************************


SQL ID: dbuap8tqp73th Plan Hash: 945689350


select count(*)

from

tt1 where owner=:l


call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch        2      0.00       0.00          0          7          0           1

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total        4      0.00       0.00          0          7          0           1


Misses in library cache during parse: 1

Misses in library cache during execute: 1

Optimizer mode: ALL_ROWS

Parsing user id: 51

Number of plan statistics captured: 1


Rows (1st) Rows (avg) Rows (max)  Row Source Operation

---------- ---------- ----------  ---------------------------------------------------

        1          1          1  SORT AGGREGATE (cr=7 pr=0 pw=0 time=276 us)

       11         11         11   BITMAP CONVERSION COUNT (cr=7 pr=0 pw=0 time=225 us cost=7 size=1072232 card=153176)

       11         11         11    BITMAP INDEX SINGLE VALUE INX_TT1_OWNER (cr=7 pr=0 pw=0 time=67 us)(object id 25884)

-- 注意,这里第一次绑定变量值为SYS的时候card=153176,执行计划很准确

********************************************************************************


SQL ID: fvp79xru6ftzd Plan Hash: 0


BEGIN :l:='SYSTEM'; END;


call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute      1      0.00       0.00          0          0          0           1

Fetch        0      0.00       0.00          0          0          0           0

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total        2      0.00       0.00          0          0          0           1


Misses in library cache during parse: 1

Misses in library cache during execute: 1

Optimizer mode: ALL_ROWS

Parsing user id: 51

********************************************************************************


SQL ID: dbuap8tqp73th Plan Hash: 945689350


select count(*)

from

tt1 where owner=:l


call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch        2      0.00       0.00          0          2          0           1

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total        4      0.00       0.00          0          2          0           1


Misses in library cache during parse: 0

Optimizer mode: ALL_ROWS

Parsing user id: 51

Number of plan statistics captured: 1


Rows (1st) Rows (avg) Rows (max)  Row Source Operation

---------- ---------- ----------  ---------------------------------------------------

        1          1          1  SORT AGGREGATE (cr=2 pr=0 pw=0 time=81 us)

        1          1          1   BITMAP CONVERSION COUNT (cr=2 pr=0 pw=0 time=68 us cost=7 size=1072232 card=153176)

        1          1          1    BITMAP INDEX SINGLE VALUE INX_TT1_OWNER (cr=2 pr=0 pw=0 time=41 us)(object id 25884)

-- 但紧接给变量传SYSTEM值,CBO认为card依然为153176,这是不正确的,也可能会影响执行计划。

********************************************************************************




以上简单的示例可以证明,绑定变量适合于OLTP系统而不适合于OLAP系统。



oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html