Убедить оптимизатор Oracle SQL в том, что индексированный (хотя и не UNIQUE) столбец на практике содержит уникальные значения

Я пишу представление, которое использует столбец сUNIQUE Индекс на это. Однако, с моей точки зрения, я уверен, что столбец будет содержать только уникальные значения (из-за условий, наложенных в WHERE пункт).

Настоящая проблема возникает, когда кто-то запрашивает представление на основе этого столбца (например, SELECT * FROM MY_VIEW WHERE COLUMN_WITH_NON_UNIQUE_INDEX = 'foo'). Оптимизатор убежден, что он будет получать много строк (потому что индекс технически не UNIQUE). Из-за этого оптимизатор избегает использования других индексов в другом месте представления в пользу полного сканирования таблицы (не круто).

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

К сожалению, я не контролирую обсуждаемую таблицу (вздох).

2 ответа

Решение

Oracle позволяет создавать уникальные (и первичный ключ) ограничения для представлений, которые не применяются, но которые предоставляют оптимизатору именно такую ​​информацию

ALTER VIEW your_view_name
  ADD CONSTRAINT name_of_constraint UNIQUE( column_with_non_unique_index )
  RELY DISABLE NOVALIDATE;

Это скажет Oracle, что он может полагаться на тот факт, что данные уникальны, но ему не нужно проверять ограничение. Однако оптимизатор сможет использовать дополнительные метаданные, которые предоставляет ограничение.

Вы можете попробовать следующее:

Соберите статистику в таблице с помощью dbms_stats, для параметра METHOD_OPT которого установлено значение FOR ALL COLUMNS SIZE AUTO. С помощью этого параметра Oracle автоматически определяет, для каких столбцов требуются гистограммы, а также количество сегментов (размер) каждой гистограммы. Вы также можете вручную указать, какие столбцы должны иметь гистограммы и размер каждой гистограммы.

dbms_stats.gather_table_stats(
ownname => 'schemaname' ,
tabname => 'tablename' ,
estimate_percent => 100 ,
method_opt => 'for all indexed columns size auto' ,
 cascade => true);
Другие вопросы по тегам