Подтвердить что ты не робот

Можно ли добавить индекс в временную таблицу Oracle?

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

Отражает ли индекс мой процесс и все остальные процессы, используя таблицу? или Это влияет только на мой процесс?

Ни один из ответов не был авторитетным, поэтому я предлагаю взятку.

4b9b3361

Ответ 1

Помогает ли индекс влиять на мой процесс и все остальные процессы, используя таблицу? или это влияет только на мой процесс?

Я предполагаю, что мы говорим о таблицах GLOBAL TEMPORARY.

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

В Oracle, DML для temporary table влияет на все процессы, а данные, содержащиеся в таблице, будут влиять только на один процесс, который их использует.

Данные в temporary table видны только внутри области сеанса. Он использует TEMPORARY TABLESPACE для хранения как данных, так и возможных индексов.

DML для a temporary table (то есть его макет, включая имена столбцов и индексы) отображается всем, у кого есть достаточные привилегии.

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

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

ЕСЛИ вы хотите, чтобы один процесс использовал индекс, а другой - не использовать его, выполните следующие действия:

  • Создайте два temporary tables с одинаковым расположением столбцов
  • Указатель на одном из них
  • Использовать индексированную или неиндексированную таблицу в зависимости от процесса

Ответ 2

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

[Изменить]  Я вижу, вы уточнили свой вопрос, и вот несколько уточненный ответ:

From:

Oracle® Database Administrator Guide
10g Release 2 (10.2)
Part Number B14231-02

"Индексы могут быть созданы во временных таблицах, а также временные , а данные в индексе имеют ту же область сеанса или транзакции, что и данные в базовой таблице.

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

Ответ 3

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

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

например. вы можете сделать:

exec dbms_stats.set_table_stats(user, 'my_temp_table', numrows=>10, numblks=>4)

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

например, если вы знаете, что в таблице temp содержится около 100 строк, вы можете:

SELECT /*+ CARDINALITY(my_temp_table 100) */ * FROM my_temp_table

Ответ 4

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

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

Здесь тестовый сценарий я запускал:

--first session
create global temporary table index_test (val number(15))
on commit preserve rows;

create unique index idx_val on index_test(val);

--second session
insert into index_test select rownum from all_tables;
select * from index_test where val=1;

Ответ 5

Вы также можете использовать подсказку динамической выборки (10g):

выберите/* + DYNAMIC_SAMPLING (3) */val от index_test где val = 1;

См. Спросить Tom

Ответ 6

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

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

Сессия 1:

SQL> create global temporary table index_test (val number(15)) on commit preserve rows;
Table created.
SQL> insert into index_test values (1);
1 row created.
SQL> commit;
Commit complete.
SQL>

Сессия 2 (пока сеанс 1 все еще подключен):

SQL> create unique index idx_val on index_test(val);
create unique index idx_val on index_test(val)
                               *
ERROR at line 1:
ORA-14452: attempt to create, alter or drop an index on temporary table already in use
SQL>

Назад к сеансу 1:

SQL> delete from index_test;
1 row deleted.
SQL> commit;
Commit complete.
SQL>

Сессия 2:

SQL> create unique index idx_val on index_test(val);
create unique index idx_val on index_test(val)
                               *
ERROR at line 1:
ORA-14452: attempt to create, alter or drop an index on temporary table already in use
SQL>

все еще не выполняется, сначала вам нужно отключить сеанс 1, или таблица должна быть усечена.

Сессия 1:

SQL> truncate table index_test;
Table truncated.
SQL>

Теперь вы можете создать индекс в сеансе 2:

SQL> create unique index idx_val on index_test(val);
Index created.
SQL>

Этот индекс, конечно, будет использоваться любым сеансом.