如何有效地利用oracle数据库中的表分区?

时间:2014-04-03 12:35:24

标签: sql oracle database-partitioning

我创建了一个分区表

CREATE TABLE orders_range(order_id NUMBER 
                         ,client_id NUMBER 
                         ,order_date DATE) 
  PARTITION BY RANGE(order_date) 
    (PARTITION orders2011 VALUES LESS THAN (to_date('1/1/2012','dd/mm/yyyy')) 
    ,PARTITION orders2012 VALUES LESS THAN (to_date('1/1/2013','dd/mm/yyyy')) 
    ,PARTITION orders2013 VALUES LESS THAN (MAXVALUE));

当我使用

选择记录时
SELECT * FROM ORDERS_RANGE partition(orders2011);
解释计划中的cpu成本为75 但是当我使用where子句进行正常查询时,cpu的成本只有6,那么在性能方面,表分区的优势是什么? 任何人都可以详细解释我吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

首先,您通常无法直接比较针对两个不同对象运行的两个不同计划的cost。一个成本为10,000的计划完全有可能比成本为10的不同计划运行得更快。您可以在单个10053跟踪中比较单个SQL语句的两个不同计划的cost (只要您记住这些是估计值,并且如果优化程序估计不正确,则许多cost值不正确,优化程序可能会选择效率较低的计划)。如果您正在尝试计算优化程序用于特定步骤的算法,那么在两个不同查询之间比较cost可能是有意义的,但这很不寻常。

其次,在您的示例中,您没有插入任何数据。通常,如果您要对表进行分区,那么您之所以这样做,是因为该表中有多GB数据。如果你比较像

这样的东西
SELECT *
  FROM unpartitioned_table_with_1_billion_rows

VS

SELECT *
  FROM partitioned_table_with_1_billion_rows
 WHERE partition_key = date '2014-04-01' -- Restricts the data to only 10 million rows
显然,分区方法将更有效率,尤其是因为您只读取4月1日分区中的1000万行而不是表中的10亿行。

如果表没有数据,那么对分区表的查询可能效率会稍微低一些,因为您在解析查询过程中需要做更多的事情。但是,从0行表中读取0行将基本上没有任何时间,因此解析时间的差异可能是无关紧要的。

通常,您不会使用ORDERS_RANGE partition(orders2011)语法来访问数据。除了对分区名称进行硬编码,这意味着您经常使用动态SQL来组合查询,您将进行更多难以解析并且您将要进行更多的分析对共享池施加更大的压力,如果有人更改了桌面上的分区,您可能会犯错误。在分区键上提供谓词并让Oracle弄清楚如何适当地修剪分区更有意义。换句话说

SELECT *   
  FROM orders_range  
 WHERE order_date < date '2012-01-01'

将是一个更明智的查询。