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

Can partitioning be bypassed in oracle sql 12c?

我有一个 table,其中约 2500 万行按时间键(月)分区。每个分区内大约有 20 万行。

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

终端用户大多查询24个月的数据范围,也就是说需要24个分区来查找数据。我们认为,如果我们在没有分区的情况下查询相同的 table,则查询比在分区的 table 上查询要快得多。因此我们认为,当查看太多(在本例中为 24 个)分区时,分区的 table 并不是那么有趣。

是否有一些参数(改变会话...)或提示我们可以用来不让优化器使用分区而是以另一种方式扫描 table?

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

所以不,你不能"ignore"或绕过分区。

而且也没有办法取消 table 的分区。您必须重新创建它,最好使用 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 rows/partition 和 25M 的总容量似乎有点小,值得对我进行分区。


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

business users query on this table with queries that, apart from filter values, are always the same.

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

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

如果是这样的话,物化视图 (MV) 可能是 "bypass" 分区的一个不错的选择。

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

您可以使用与基础 table 不同的方式将它们分区(或不分区)。如果您的查询通常处理 "many" 行,但处理 return "few",那么使用 MV 的优势可能会快得多。