2017-02-28 72 views
4

我正在做一个概念证明,我正在试验一个奇怪的行为。 我有一个按日期字段进行范围分区的表格,如果我设置了一个固定日期或由SYSDATE创建了一个查询,那么查询的成本会发生很大变化。oracle过滤器解释计划分区

这些在解释计划:

SQL> SELECT * 
    2 FROM TP_TEST_ELEMENTO_TRAZABLE ET 
    3 WHERE ET.FEC_RECEPCION 
    4 BETWEEN TRUNC(SYSDATE-2) AND TRUNC(SYSDATE-1) 
    5 ; 

5109 filas seleccionadas. 


Plan de Ejecuci¾n 
---------------------------------------------------------- 
Plan hash value: 1151442660 

------------------------------------------------------------------------------------------------------------------------ 
| Id | Operation     | Name      | Rows | Bytes | Cost (%CPU)| Time  | Pstart| Pstop | 
------------------------------------------------------------------------------------------------------------------------ 
| 0 | SELECT STATEMENT   |       | 5008 | 85136 | 4504 (8)| 00:00:55 |  |  | 
|* 1 | FILTER     |       |  |  |   |   |  |  | 
| 2 | PARTITION RANGE ITERATOR|       | 5008 | 85136 | 4504 (8)| 00:00:55 | KEY | KEY | 
|* 3 | TABLE ACCESS FULL  | TP_TEST_ELEMENTO_TRAZABLE | 5008 | 85136 | 4504 (8)| 00:00:55 | KEY | KEY | 
------------------------------------------------------------------------------------------------------------------------ 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    1 - filter(TRUNC([email protected]!-2)<=TRUNC([email protected]!-1)) 
    3 - filter("ET"."FEC_RECEPCION">=TRUNC([email protected]!-2) AND "ET"."FEC_RECEPCION"<=TRUNC([email protected]!-1)) 


EstadÝsticas 
---------------------------------------------------------- 
      1 recursive calls 
      0 db block gets 
     376 consistent gets 
      0 physical reads 
      0 redo size 
    137221 bytes sent via SQL*Net to client 
     4104 bytes received via SQL*Net from client 
     342 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     5109 rows processed 

使用固定日期:

SQL> SELECT * 
    2 FROM TP_TEST_ELEMENTO_TRAZABLE ET 
    3 WHERE ET.FEC_RECEPCION 
    4 BETWEEN TO_DATE('26/02/2017', 'DD/MM/YYYY') AND TO_DATE('27/02/2017', 'DD/MM/YYYY') 
    5 ; 

5109 filas seleccionadas. 


Plan de Ejecuci¾n 
---------------------------------------------------------- 
Plan hash value: 3903280660 

----------------------------------------------------------------------------------------------------------------------- 
| Id | Operation    | Name      | Rows | Bytes | Cost (%CPU)| Time  | Pstart| Pstop | 
----------------------------------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT   |       | 5008 | 85136 | 11 (0)| 00:00:01 |  |  | 
| 1 | PARTITION RANGE ITERATOR|       | 5008 | 85136 | 11 (0)| 00:00:01 | 607 | 608 | 
|* 2 | TABLE ACCESS FULL  | TP_TEST_ELEMENTO_TRAZABLE | 5008 | 85136 | 11 (0)| 00:00:01 | 607 | 608 | 
----------------------------------------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    2 - filter("ET"."FEC_RECEPCION"<=TO_DATE(' 2017-02-27 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 


EstadÝsticas 
---------------------------------------------------------- 
      1 recursive calls 
      0 db block gets 
     376 consistent gets 
      0 physical reads 
      0 redo size 
    137221 bytes sent via SQL*Net to client 
     4104 bytes received via SQL*Net from client 
     342 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     5109 rows processed 

那是什么产生的4504成本和11成本区别?

感谢提前:)

+2

简短的回答是:“成本”并不意味着比较两个不同的查询(即使它们看起来非常相似);它们只是**,意味着一次比较一个查询的不同计划。比较不同的查询时,最好比较基数估计。 – mathguy

+1

https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:313416745628 –

+1

https://jonathanlewis.wordpress.com/2017/02/28/cost-是时,再次/ –

回答

5

所不同的是,因为当你使用SYSDATE,它需要的任何分区的潜力。例如,如果您每天进行分区,那么您需要访问的分区在今天和明天之间会有所不同。因此,该计划是KEY:KEY,这意味着实际分区在运行时被解析。

有了固定的日期,我们知道在编译时它解决了哪个分区。而且,由于它解析为单个分区,因此更“精确”地进行计算。