Как создать sql разделов для нескольких столбцов? - PullRequest
0 голосов
/ 27 января 2020

Я пытаюсь создать разделы для таблицы. Я хочу создать разделы для 2 разных столбцов. Возможно ли это?

Так что это работает:

  ALTER TABLE MY)TABLE MODIFY
    PARTITION BY RANGE(SETTLEMENT_DATE) INTERVAL(NUMTODSINTERVAL(1,'day'))
( partition MY_PARTITION values less than (to_date('2019-06-01', 'yyyy-mm-dd')));

Это то, что я хотел бы сделать, но это не работает:

  ALTER TABLE MY_TABLE MODIFY
    PARTITION BY RANGE(FILE_SUBMISSION_DATE_TIME) INTERVAL(NUMTODSINTERVAL(1,'day'))
( partition MY_PARTITION values less than (to_date('2016-06-01', 'yyyy-mm-dd'))),
    PARTITION BY RANGE(FILE_ACK_DATE_TIME) INTERVAL(NUMTODSINTERVAL(1,'day'))
( partition MY_PARTITION_2 values less than (to_date('2016-06-01', 'yyyy-mm-dd')));

Ответы [ 2 ]

0 голосов
/ 27 января 2020

То, что я пытался сделать, невозможно. Можно создавать разделы диапазона, используя ключи разделения на несколько столбцов, но не при создании интервальных разделов. Подробнее здесь .

0 голосов
/ 27 января 2020

Вы можете разбить на два столбца двумя способами:

  • Многораздельное разбиение
  • Составное разбиение (один столбец разделения, один столбец подраздела)

Многостолбцовое разбиение

При этом используется первый столбец, чтобы выбрать, в какой раздел помещать строку. Второй столбец оценивается только при значении ie. Это может привести к тому, что строки в разделе, которого вы не ожидали:

create table t (
  c1 int, c2 int, c3 int
) partition by range ( c1, c2 ) (
  partition p0 values less than ( 1, 1 ),
  partition p1 values less than ( 2, 2 ),
  partition p2 values less than ( 3, 3 )
);

insert into t values ( 0, 0,  1 );
insert into t values ( 0, 99, 2 );
insert into t values ( 1, 1,  3 );

select * from t partition ( p0 );

C1    C2     C3   
    0     0     1 
    0    99     2 

Фильтрация по второму столбцу в списке приведет к минимальному сокращению раздела:

alter session set statistics_level = all;
set serveroutput off

select * from t 
where  c2 = 0;

select * 
from   table(dbms_xplan.display_cursor(null, null, 'ROWSTATS LAST +PARTITION'));

----------------------------------------------------------------------------------------    
| Id  | Operation                    | Name | Starts | E-Rows | Pstart| Pstop | A-Rows |    
----------------------------------------------------------------------------------------    
|   0 | SELECT STATEMENT             |      |      1 |        |       |       |      1 |    
|   1 |  PARTITION RANGE MULTI-COLUMN|      |      1 |      1 |KEY(MC)|KEY(MC)|      1 |    
|*  2 |   TABLE ACCESS FULL          | T    |      3 |      1 |KEY(MC)|KEY(MC)|      1 |    
----------------------------------------------------------------------------------------

(обратите внимание на Starts = 3 для TABLE ACCESS FULL; это означает, что он читает все разделы)

Составное разбиение

Это «двухуровневое» разбиение. База данных сначала разбивает строки в разделе верхнего уровня. Затем далее подразделяется на второй уровень.

Ключевое различие между этим и несколькими столбцами в том, что вы можете иметь разные методы разбиения для каждого. например, range-ha sh, ha sh -list, et c.

create table t (
  c1 int, c2 int, c3 int
) partition by range ( c1 ) 
  subpartition by range ( c2 )  
  subpartition template (
    subpartition s0 values less than ( 1 ),
    subpartition s100 values less than ( 101 )
  ) (
  partition p0 values less than ( 1 ),
  partition p1 values less than ( 2 ),
  partition p2 values less than ( 3 )
);

insert into t values ( 0, 0,  1 );
insert into t values ( 0, 99, 2 );
insert into t values ( 1, 1,  3 );

select * from t partition ( p0 );

C1     C2     C3   
    0     0     1 
    0    99     2 

select * from t subpartition ( p0_s0 );

C1     C2     C3   
    0     0     1 

Опять же, фильтрация столбца подразделения делает минимальное сокращение раздела. База данных сначала просканирует все разделы верхнего уровня. Затем только сокращайте подразделы в этих:

select * from t 
where  c2 = 0;

select * 
from   table(dbms_xplan.display_cursor(null, null, 'ROWSTATS LAST +PARTITION'));

-----------------------------------------------------------------------------------    
| Id  | Operation               | Name | Starts | E-Rows | Pstart| Pstop | A-Rows |    
-----------------------------------------------------------------------------------    
|   0 | SELECT STATEMENT        |      |      1 |        |       |       |      1 |    
|   1 |  PARTITION RANGE ALL    |      |      1 |      1 |     1 |     3 |      1 |    
|   2 |   PARTITION RANGE SINGLE|      |      3 |      1 |     1 |     1 |      1 |    
|*  3 |    TABLE ACCESS FULL    | T    |      3 |      1 |       |       |      1 |    
----------------------------------------------------------------------------------- 

Обратите внимание на операцию PARTITION RANGE SINGLE - это означает, что база данных получила доступ только к одному из подразделов.

В зависимости от схемы разбиения и распределения значений это может привести к значительному сокращению числа прочитанных строк. Вам нужно будет попробовать различные методы и границы раздела, чтобы понять, поможет ли это вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...