代码之家  ›  专栏  ›  技术社区  ›  EvilTeach

在Oracle临时表上放置索引安全吗?

  •  13
  • EvilTeach  · 技术社区  · 17 年前

    我读到过,一个人不应该分析临时表,因为它会破坏其他人的表统计数据。指数呢?如果我在程序的持续时间内在表上放置一个索引,使用该表的其他程序会受到该索引的影响吗?

    索引是否会影响我的进程以及使用该表的所有其他进程? 或者它只影响我的过程吗?

    这些回应都没有权威性,所以我提供了贿赂。

    6 回复  |  直到 14 年前
        1
  •  13
  •   A J Qarshi    13 年前

    索引是否会影响我的流程以及使用该表的所有其他流程?或者它会单独影响我的过程吗?

    GLOBAL TEMPORARY

    .

    Oracle , DML temporary table 影响所有进程,而表中包含的数据只会影响使用它们的一个进程。

    a中的数据 TEMPORARY TABLESPACE

    数据操作语言 为了一个

    这意味着 存在 索引的变化将影响您的进程以及使用该表的其他进程,因为任何修改表中数据的进程 临时表 还必须修改索引。

    数据 相反,表(以及索引)中包含的内容只会影响创建它们的进程,甚至对其他进程都不可见。

    如果您希望一个进程使用索引,而另一个进程不使用索引,请执行以下操作:

    • temporary tables 具有相同的列布局
    • 其中一个的索引
    • 根据流程使用索引表或非索引表
        2
  •  9
  •   dpbradley    17 年前

    我假设您指的是真正的Oracle临时表,而不仅仅是临时创建然后删除的常规表。是的,在临时表上创建索引是安全的,它们将根据与常规表和索引相同的规则使用。

    [编辑] 我看到你已经完善了你的问题,这里有一个稍微完善的答案:

    发件人:

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

    “可以在临时表上创建索引。它们也是临时的 索引中的数据与基础表中的数据具有相同的会话或事务范围 ."

        3
  •  6
  •   Chi    17 年前

    你问的是两个不同的问题,索引和统计。 对于索引,是的,您可以在临时表上创建索引,它们将照常维护。

    对于统计数据,我建议您显式设置表的统计数据,以表示查询时表的平均大小。如果你只是让oracle自己收集统计数据,统计过程不会在表中找到任何东西(因为根据定义,表中的数据是事务的本地数据),因此它会返回不准确的结果。

    例如,您可以执行以下操作:

    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

        4
  •  2
  •   Plasmer    17 年前

    好吧,我试过了,索引是可见的,并在第二次会话中使用。如果你真的需要索引,为你的数据创建一个新的全局临时表会更安全。

    当任何其他会话正在访问表时,您也无法创建索引。

    这是我运行的测试用例:

    --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
  •  1
  •   sergikpas diederikh    12 年前

    您还可以使用动态采样提示(10g):

    选择/*+动态采样(3)*/val 来自index_test 其中val=1;

    Ask Tom

        6
  •  0
  •   Wernfried Domscheit    12 年前

    当临时表被另一个会话使用时,您无法在临时表上创建索引,所以答案是:不,它不能影响任何其他进程,因为这是不可能的。

    现有索引仅影响当前会话,因为对于任何其他会话,临时表都显示为空,因此它无法访问任何索引值。

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

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

    第2节:

    在index_test(val)上创建唯一索引idx_val
    *
    第1行错误:
    ORA-14452:尝试在已使用的临时表上创建、更改或删除索引
    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>
    

    当然,任何会话都将使用此索引。