Является ли ora_hash детерминированным? - PullRequest
12 голосов
/ 26 февраля 2012

Я работаю с базой данных Oracle, и мне нужно иметь возможность разделить данные в таблице. Я понимаю, что в Rracle есть функция ora_hash, которая может разбивать данные на сегменты. Является ли функция ora_hash детерминированной?

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

Например, в одном запросе я мог бы попросить первые два сегмента:

SELECT * FROM sales WHERE ORA_HASH(cust_id, 9) in (0,1);

В следующем запросе я мог бы попросить 2-е и 3-е ведро:

SELECT * FROM sales WHERE ORA_HASH(cust_id, 9) in (1,2);

В приведенном выше примере, ora_hash всегда будет делить таблицу на те же самые 10 сегментов? Предположим, что данные в таблицах не изменились. Будет ли второе ведро (ведро 1) идентичным в обоих запросах?

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

Ответы [ 2 ]

16 голосов
/ 28 февраля 2012

ORA_HASH определенно является детерминированным для типов данных, которые можно использовать для разделения, таких как NUMBER, VARCHAR, DATE и т. Д.

Но ORA_HASH является , а не детерминированным по крайней мере для некоторых других типов данных, таких как CLOB.


Мой ответ основан на этой статье Джонатана Льюиса о ORA_HASH.

Джонатан Льюис не говорит явно, что они являются детерминированными, но он упоминает, что ORA_HASH «кажется, что это функция, используемая внутри - с нулевым начальным числом - для определения того, к какому разделу относится строка в хэш-таблице с разделами» , И если он используется для разбиения хэша, то он должен быть детерминированным, иначе соединения с разбиением не будут работать.

Чтобы показать, что ORA_HASH может быть недетерминированным для некоторых типов данных, выполните следующий запрос. Это из комментария в той же статье:

with src as (select to_clob('42') val from dual connect by level<=5)
select val,ora_hash(val,7) from src order by 2;

Удивительно, но такие же проблемы случаются с dbms_sqlhash.gethash.

5 голосов
/ 26 февраля 2012

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

ORA_HASH определенно является детерминированным для типов данных, которые можно использовать для разделения, таких как NUMBER, VARCHAR, DATE и т. Д.

Но ORA_HASH не является детерминированным по крайней мере для некоторых других типов данных, таких как CLOB.

...