Можно ли добавить индекс в временную таблицу Oracle?
Я читал, что не следует анализировать временную таблицу, поскольку она закручивает статистику таблицы для других. Как насчет индекса? Если я помещу индекс в таблицу в течение всей моей программы, могут ли другие индексы использовать эту таблицу?
Отражает ли индекс мой процесс и все остальные процессы, используя таблицу?
или Это влияет только на мой процесс?
Ни один из ответов не был авторитетным, поэтому я предлагаю взятку.
Ответы
Ответ 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>
Этот индекс, конечно, будет использоваться любым сеансом.