Безопасно ли помещать индекс во временную таблицу Oracle?

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

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

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

6 ответов


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

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

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

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

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

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

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

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

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

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

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

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

From:

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

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

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


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

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

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

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

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

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

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


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

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

вот тестовый пример, который я запустил:

--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;

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

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

посмотреть Спросить Тома


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

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

сеанс 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>

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