在 oracle sql 12c 中可以绕过分区吗?

Posted

技术标签:

【中文标题】在 oracle sql 12c 中可以绕过分区吗?【英文标题】:Can partitioning be bypassed in oracle sql 12c? 【发布时间】:2019-08-19 08:43:31 【问题描述】:

我有一个按时间键(月)分区的大约 25M 行的表。每个分区内大约有 200K 行。

我们在 BI 上下文中使用此表,这意味着业务用户在此表上查询时,除了过滤器值之外,这些查询始终相同。

大多数最终用户查询 24 个月的数据范围,这意味着需要 24 个分区来查找数据。我们觉得,如果我们在没有分区的情况下查询同一张表,查询速度远远快于分区表。所以我们相信,当查看太多(在本例中为 24 个)分区时,分区表并没有那么有趣。

是否有一些参数(alter session ...)或提示我们可以用来不让优化器使用分区但以另一种方式扫描表?

【问题讨论】:

您应该为过滤器中使用的列创建本地索引。每个分区都有目录中的记录。所以 oracle 正在通过目录中的键监视每个分区。同时压缩旧分区可以减少IO操作 尝试禁用分区并行扫描。select/*+ NO_PARALLEL*/ * from 或降低并行级别select/*+ PARALLEL 2 */ * from 你有本地索引吗?如果是,则尝试使用 GLOBAL 索引。如果您使用本地索引查询 24 个分区,那么这意味着 Oracle 必须扫描 24 个不同的索引 - 这当然需要一些时间。 【参考方案1】:

每个分区都有自己的段。因此,数据库将每个行的行物理存储在不同的位置。假设您需要访问该表,则必须读取所有相关分区。

所以不,您不能“忽略”或绕过分区。

而且也没有办法取消对表的分区。您必须重新创建它,最好使用dbms_redefinition 完成。

或者您可以将分区合并在一起:

create table t ( 
  c1, c2, c3, c4
) partition by range ( c1 ) (
  partition p0 values less than ( 10 ),
  partition p1 values less than ( 20 ),
  partition p2 values less than ( 30 ),
  partition p3 values less than ( 40 ),
  partition p4 values less than ( 50 )
) as
  select level c1, sysdate + level c2 ,
         round ( dbms_random.value ( 1, 100 ) ) c3,
         dbms_random.string ( 'a', 20 ) c4
  from   dual
  connect by level < 50;

alter table t 
  merge partitions p0, p1, p2, p3, p4
  into partition p4;

select partition_name 
from   user_tab_partitions
where  table_name = 'T';

PARTITION_NAME   
P4         

当然,查询性能只是分区的原因之一。使用它还有很多其他原因,例如:

通过drop/truncate partition 快速轻松地归档数据 使用exchange partition 快​​速加载数据 通过将分区标记为read only 来阻止人们更改旧数据 将旧数据存储在较慢(便宜)的磁盘上 ...

因此,在清除它们之前,有必要检查一下您是否没有使用其他分区功能。

也就是说,大约 200k 行/分区和总共 25M 对我来说似乎有点小值得分区。


从技术上讲,还有另一种选择......

业务用户使用以下查询查询此表,除了 过滤器值,始终相同。

这些是聚合(count、sum、avg 等)查询吗?例如:

  select customer_id, count(*)
  from   ...
  where  ...
  group  by customer_id

如果是这样,物化视图 (MV) 可能是“绕过”分区的好选择。

create materialized view mv as
  select customer_id, count(*)
  from   ...
  where  ...
  group  by customer_id

您可以以与基表不同的方式对这些进行分区(或不分区)。如果您的查询通常处理“许多”行但返回“少数”行,那么使用 MV 可能会更快。

【讨论】:

以上是关于在 oracle sql 12c 中可以绕过分区吗?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle12c:自动分区表

Oracle 分区和本地 Indexex (12c)

Oracle 12C 新特性之move (非分区表)table online

Oracle动态创建时间分区,以及Oracle12c中快速创建自增列

Oracle 12C 新特性之表分区带 异步全局索引异步维护(一次addtruncatedropspiltmerge多个分区)

如何在Oracle 12C中添加多个分区 (Doc ID 1482456.1)