您的位置:首页 > 数据库 > Oracle

Oracle_绑定变量窥探测试

2015-08-14 00:35 651 查看
绑定变量窥探受隐含参数:_optim_peek_user_binds的限制,自9i之后改参数默认为True,为自动开启状态:

查询sql

SQL> col name for a50

SQL> col value for a10

SQL> col description for a100

SQL> select a.ksppinm name, b.ksppstvl value, a.ksppdesc description from x$ksppi a, x$ksppcv b where a.indx = b.indx

  2  and a.ksppinm like '%_optim_peek_user_binds%';

NAME                                               VALUE      DESCRIPTION

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

_optim_peek_user_binds                             TRUE       enable peeking of user binds

接下来,我们测试一个绑定变量窥探的示例:

1、创建测试表t1

      create table sdxj.t1 as select * from dba_objects;

2、创建索引

      create index idx_t1 on sdxj.t1 (object_id);

3、对表进行分析

       exec dbms_stats.gather_table_stats(ownname => 'SDXJ',tabname => 'T1',estimate_percent => 100,CASCADE => TRUE,method_opt => 'for all columns size 1',degree => 8,no_invalidate    => FALSE);

4、执行以下两个sql

      4.1、SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999  AND  1000;

      4.2、SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999  AND  6000;

      4.3、查看sql执行情况

SQL> SELECT  SQL_TEXT,SQL_ID,VERSION_COUNT ,executions FROM V$SQLAREA WHERE SQL_TEXT LIKE 'SELECT COUNT(*) FROM SDXJ.T1%';

SQL_TEXT                                                               SQL_ID               VERSION_COUNT EXECUTIONS

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

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999 AND 1000      gxgb577ncwrm2                 1     1

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999 AND 60000     6d2d6y357kfws                 1     1

SQL> col plan_table_output for a200

SQL> set long 900

SQL> set pages 800

SQL> SELECT * FROM TABLE (DBMS_XPLAN.DISPLAY_CURSOR('gxgb577ncwrm2','0','advanced'));

----sql1 执行计划----

PLAN_TABLE_OUTPUT

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

SQL_ID  gxgb577ncwrm2, child number 0

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

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999 AND 1000

Plan hash value: 1970818898

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

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

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

|   0 | SELECT STATEMENT  |        |       |       |     2 (100)|          |

|   1 |  SORT AGGREGATE   |        |     1 |     5 |            |          |

|*  2 |   INDEX RANGE SCAN| IDX_T1 |     3 |    15 |     2   (0)| 00:00:01 |

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

Query Block Name / Object Alias (identified by operation id):

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

   1 - SEL$1

   2 - SEL$1 / T1@SEL$1

Outline Data

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

  /*+

      BEGIN_OUTLINE_DATA

      IGNORE_OPTIM_EMBEDDED_HINTS

      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')

      DB_VERSION('11.2.0.1')

      ALL_ROWS

      OUTLINE_LEAF(@"SEL$1")

      INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."OBJECT_ID"))

      END_OUTLINE_DATA

  */

Predicate Information (identified by operation id):

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

   2 - access("OBJECT_ID">=999 AND "OBJECT_ID"<=1000)

Column Projection Information (identified by operation id):

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

   1 - (#keys=0) COUNT(*)[22]

Note

-----

   - SQL plan baseline SQL_PLAN_f02470f3q2mcga9a6a0a8 used for this statement

已选择48行。

---sql2 执行计划---

Plan hash value: 2101382132

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

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

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

|   0 | SELECT STATEMENT      |        |       |       |    46 (100)|          |

|   1 |  SORT AGGREGATE       |        |     1 |     5 |            |          |

|*  2 |   INDEX FAST FULL SCAN| IDX_T1 | 54911 |   268K|    46   (3)| 00:00:01 |

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

Query Block Name / Object Alias (identified by operation id):

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

   1 - SEL$1

   2 - SEL$1 / T1@SEL$1

Outline Data

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

  /*+

      BEGIN_OUTLINE_DATA

      IGNORE_OPTIM_EMBEDDED_HINTS

      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')

      DB_VERSION('11.2.0.1')

      ALL_ROWS

      OUTLINE_LEAF(@"SEL$1")

      INDEX_FFS(@"SEL$1" "T1"@"SEL$1" ("T1"."OBJECT_ID"))

      END_OUTLINE_DATA

  */

Predicate Information (identified by operation id):

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

   2 - filter(("OBJECT_ID"<=60000 AND "OBJECT_ID">=999))

Column Projection Information (identified by operation id):

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

   1 - (#keys=0) COUNT(*)[22]

已选择44行。

现在我们将上述两个SQL进行改造,使其可以用绑定变量的形式。

SQL> var x number;

SQL> var y number;

SQL> exec :x :=999

    PL/SQL 过程已成功完成。

SQL> exec :y :=1000

   PL/SQL 过程已成功完成。

---执行查询sql

SQL> SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN :x AND :y;

  COUNT(*)

----------

         2

---查询sql执行情况

SQL> SELECT  SQL_TEXT,SQL_ID,VERSION_COUNT ,executions FROM V$SQLAREA WHERE SQL_TEXT LIKE 'SELECT COUNT(*) FROM SDXJ.T1%';

SQL_TEXT                                                               SQL_ID               VERSION_COUNT EXECUTIONS

---------------------------------------------------------------------- -------------------- ------------- ----------
SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN :x AND :y         65r6vbdf4n1vk                            1     1

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999 AND 1000      gxgb577ncwrm2                 1     1

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999 AND 60000     6d2d6y357kfws                 1     1

----查看执行计划

SQL> SELECT * FROM TABLE (DBMS_XPLAN.DISPLAY_CURSOR('65r6vbdf4n1vk','0','advanced'));

PLAN_TABLE_OUTPUT

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

SQL_ID  65r6vbdf4n1vk, child number 0

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

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN :x AND :y

Plan hash value: 2351893609

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

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

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

|   0 | SELECT STATEMENT   |        |       |       |     2 (100)|          |

|   1 |  SORT AGGREGATE    |        |     1 |     5 |            |          |

|*  2 |   FILTER           |        |       |       |            |          |

|*  3 |    INDEX RANGE SCAN| IDX_T1 |     3 |    15 |     2   (0)| 00:00:01 |

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

Query Block Name / Object Alias (identified by operation id):

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

   1 - SEL$1

   3 - SEL$1 / T1@SEL$1

Outline Data

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

  /*+

      BEGIN_OUTLINE_DATA

      IGNORE_OPTIM_EMBEDDED_HINTS

      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')

      DB_VERSION('11.2.0.1')

      ALL_ROWS

      OUTLINE_LEAF(@"SEL$1")

      INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."OBJECT_ID"))

      END_OUTLINE_DATA

  */

Peeked Binds (identified by position):

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

   1 - :X (NUMBER): 999

   2 - :Y (NUMBER): 1000

Predicate Information (identified by operation id):

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

   2 - filter(:X<=:Y)

   3 - access("OBJECT_ID">=:X AND "OBJECT_ID"<=:Y)

Column Projection Information (identified by operation id):

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

   1 - (#keys=0) COUNT(*)[22]

Note

-----

   - SQL plan baseline SQL_PLAN_b0hdzdb9t6f6911bbd8aa used for this statement

已选择56行。

下面执行第二个sql语句,将y改为60000

SQL> exec :y :=60000

PL/SQL 过程已成功完成。

SQL> SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN :x AND :y;

  COUNT(*)

----------

     58180

SQL> SELECT  SQL_TEXT,SQL_ID,VERSION_COUNT ,executions FROM V$SQLAREA WHERE SQL_TEXT LIKE 'SELECT COUNT(*) FROM SDXJ.T1%';

SQL_TEXT                                                               SQL_ID               VERSION_COUNT EXECUTIONS

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

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN :x AND :y         65r6vbdf4n1vk                            1     2

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999 AND 1000      gxgb577ncwrm2                 1     1

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN 999 AND 60000     6d2d6y357kfws                 1     1

SQL> SELECT * FROM TABLE (DBMS_XPLAN.DISPLAY_CURSOR('65r6vbdf4n1vk','0','advanced'));

PLAN_TABLE_OUTPUT

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

SQL_ID  65r6vbdf4n1vk, child number 0

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

SELECT COUNT(*) FROM SDXJ.T1 WHERE OBJECT_ID BETWEEN :x AND :y

Plan hash value: 2351893609

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

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

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

|   0 | SELECT STATEMENT   |        |       |       |     2 (100)|          |

|   1 |  SORT AGGREGATE    |        |     1 |     5 |            |          |

|*  2 |   FILTER           |        |       |       |            |          |

|*  3 |    INDEX RANGE SCAN| IDX_T1 |     3 |    15 |     2   (0)| 00:00:01 |

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

Query Block Name / Object Alias (identified by operation id):

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

   1 - SEL$1

   3 - SEL$1 / T1@SEL$1

Outline Data

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

  /*+

      BEGIN_OUTLINE_DATA

      IGNORE_OPTIM_EMBEDDED_HINTS

      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')

      DB_VERSION('11.2.0.1')

      ALL_ROWS

      OUTLINE_LEAF(@"SEL$1")

      INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."OBJECT_ID"))

      END_OUTLINE_DATA

  */

Peeked Binds (identified by position):

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

   1 - :X (NUMBER): 999

   2 - :Y (NUMBER): 1000

Predicate Information (identified by operation id):

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

   2 - filter(:X<=:Y)

   3 - access("OBJECT_ID">=:X AND "OBJECT_ID"<=:Y)

Column Projection Information (identified by operation id):

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

   1 - (#keys=0) COUNT(*)[22]

Note

-----

   - SQL plan baseline SQL_PLAN_b0hdzdb9t6f6911bbd8aa used for this statement

已选择56行。

SQL>

从上面执行计划可以看出,依然走索引:INDEX RANGE SCAN| IDX_T1 并且绑定变量值仍然为999~1000;

现在,我们在进行另外一个测试。让其走 INDEX FAST FULL SCAN| 索引,测试方法同上,首先创建表T2

采用绑定变量时,首先带入只999 和60000 然后在测试999 h和1000 查看执行计划情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  测试 优化