我已经读过不应该分析临时表,因为它会破坏其他人的表统计信息。索引呢?如果我在我的程序期间在表上放置一个索引,使用该表的其他程序会受到该索引的影响吗?
索引是否会影响我的进程以及使用该表的所有其他进程?或者它会单独影响我的流程吗?
没有一个回应是权威的,所以我提供所说的贿赂。
我已经读过不应该分析临时表,因为它会破坏其他人的表统计信息。索引呢?如果我在我的程序期间在表上放置一个索引,使用该表的其他程序会受到该索引的影响吗?
索引是否会影响我的进程以及使用该表的所有其他进程?或者它会单独影响我的流程吗?
没有一个回应是权威的,所以我提供所说的贿赂。
索引是否会影响我的进程以及使用该表的所有其他进程?或者它会单独影响我的过程吗?
我假设我们在谈论GLOBAL TEMPORARY
桌子。
将临时表想象成多个表,每个进程从存储在系统字典中的模板动态创建和删除这些表。
在Oracle
, DML
of atemporary table
影响所有进程,而表中包含的数据将仅影响使用它们的一个进程。
a 中的数据temporary table
仅在会话范围内可见。它用于TEMPORARY TABLESPACE
存储数据和可能的索引。
DML
对于 a temporary table
(即它的布局,包括列名和索引)对具有足够权限的每个人都是可见的。
这意味着索引的存在将影响您的进程以及使用该表的其他进程,因为任何修改数据的进程temporary table
也必须修改索引。
相反,包含在表中(以及索引中)的数据只会影响创建它们的进程,甚至不会对其他进程可见。
如果您希望一个进程使用索引而另一个进程不使用它,请执行以下操作:
temporary tables
具有相同列布局我假设您指的是真正的 Oracle 临时表,而不仅仅是临时创建然后删除的常规表。是的,在临时表上创建索引是安全的,它们将根据与常规表和索引相同的规则使用。
[编辑]我看到你已经完善了你的问题,这里有一个稍微精致的答案:
从:
Oracle® Database Administrator's Guide
10g Release 2 (10.2)
Part Number B14231-02
“可以在临时表上创建索引。它们也是临时的,索引中的数据与基础表中的数据具有相同的会话或事务范围。”
如果您需要在事务范围内进行有效处理的索引,那么我想您必须在查询中明确提示它,因为统计信息不会显示表的行。
你问的是两个不同的东西,索引和统计。对于索引,是的,您可以在临时表上创建索引,它们将照常维护。
对于统计信息,我建议您在查询时显式设置表的统计信息以表示表的平均大小。如果您只是让 oracle 自己收集统计信息,那么 stats 进程将不会在表中找到任何内容(因为根据定义,表中的数据对于您的事务来说是本地的),因此它将返回不准确的结果。
例如你可以这样做:
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;
当临时表被另一个会话使用时,您不能在临时表上创建索引,因此答案是:不,它不会影响任何其他进程,因为这是不可能的。
现有索引仅影响您当前的会话,因为对于任何其他会话,临时表显示为空,因此它无法访问任何索引值。
第 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>
现在您可以在 Session 2 中创建索引:
SQL> create unique index idx_val on index_test(val);
Index created.
SQL>
这个索引当然会被任何会话使用。