Запросить точное разделение, когда таблица разделена на хеш - PullRequest
1 голос
/ 24 октября 2019

Когда я хочу сделать запрос к одному разделу, я обычно использую что-то вроде этого:

Select * from t (partition p1)

Но когда вам нужно сделать запрос в вашем коде pl / sql, возникает необходимость использовать execute immediate исинтаксический анализ оператора.

Хорошо, для таблицы, разбитой на RANGE (пусть это будет SOME_DATE типа date), я могу обойти это как

Select * from t where some_date <= :1 and some_date > :2

Предполагая :1 и :2 обозначает связи разделов.

Что касается таблицы с разделами LIST, я могу легко указать точное значение поля ключа раздела, например

Select * from t where part_key = 'X'

А как насчет разделения HASH? Например, у меня есть таблица, разделенная на hash(id) на 16 разделов. И у меня есть 16 заданий, каждое из которых обрабатывает свой собственный раздел. Поэтому я должен использовать это следующим образом

Select * from t (partition p<n>)

Вопрос: могу ли я сделать это, например,

Select * from t where hash(id) = :1

Для принудительного удаления разделов взять весь n-й раздел?

Ничего страшного, когда у вас всего 16 разделов, но в моем случае у меня есть составное разбиение (date + hash (id)), поэтому каждый раз, когда задание обрабатывает раздел, это всегда новый sql_id, и он быстро заканчиваетсярост общего пула

1 Ответ

2 голосов
/ 25 октября 2019

Похоже, Oracle внутренне использует функцию ora_hash (по крайней мере, начиная с 10g), чтобы присвоить значение разделу. Таким образом, вы можете использовать это для чтения всех данных из одного раздела. К сожалению, хотя, поскольку вы будете выполнять запрос типа

select *
  from t
 where ora_hash( id, 9 ) = 6

, чтобы получить все данные в 6-м из 8-ти хеш-разделов, я ожидаю, что Oracle будет вынужден читать каждый раздел в таблице (и вычислять хеш для каждого id), потому что оптимизатор не будет достаточно умным, чтобы признать, что ваше выражение в точности соответствует его стратегии внутреннего разделения. Поэтому я не думаю, что вы захотите сделать это, чтобы разделить данные для обработки разными потоками.

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

...