【问题标题】:Oracle IOT to mimic SQL Server composite clustered indexOracle IOT 模仿 SQL Server 复合聚集索引
【发布时间】:2014-01-26 03:31:29
【问题描述】:

我希望我的 Oracle 行按照我的复合主键(WORK_DATE、EMP_ID)的确切升序排序。在 SQL Server 中,创建聚集索引可以轻松神奇地解决问题。乍一看,Oracle 的 ORGANIZATION INDEX(或 IOT)似乎提供了一个可行的解决方案,但事实并非如此。

以下 DDL 说明了该问题。我已经使数据尽可能真实,特别是我有一个相当大的 VARCHAR 字段,该字段的大小因行而异(这可能会阻止 Oracle 重新排序行的存储)。

我正在寻找一种解决方案,该解决方案可以使行以与查询 #2 的输出相同的方式存储,而临时用户不必添加“ORDER BY 1, 2”。我有笨拙的用户忘记添加 ORDER BY 语句,他们 CTRL+END 到底部,认为他们正在获取最新的 WORK_DATE。我不想通过创建一个包含嵌入式 ORDER BY 语句的视图来解决这个问题。您能否建议对 DDL 声明进行更正?也许我需要在“ORGANIZATION INDEX”关键字之后添加额外的子句或参数?谢谢你的帮助。

CREATE TABLE EMPLOYEE_HOURS (
      WORK_DATE       DATE          NOT NULL 
    , EMP_ID          VARCHAR2(15)  NOT NULL
    , HOURS_WORKED    NUMBER(22)    NOT NULL
    , WORK_COMMENT    VARCHAR2(150) NOT NULL    
    , ROW_INSERT_DATE TIMESTAMP DEFAULT SYSTIMESTAMP
    , CONSTRAINT EMPLOYEE_HOURS_PK PRIMARY KEY (WORK_DATE, EMP_ID)
) ORGANIZATION INDEX;


/* create test data that mimics my real world data */
BEGIN
    FOR loop_id IN 1 .. 10000
    LOOP

    INSERT INTO EMPLOYEE_HOURS VALUES (
          TRUNC(SYSDATE) - TRUNC(dbms_random.value(-150, 150))
        , UPPER(dbms_random.string('A', 3)) 
                       || TRUNC(dbms_random.value(1000, 999999)) 
        , dbms_random.value(0.5, 18.5)
        , regexp_replace(SUBSTR(LOWER(dbms_random.string('A', 100))
                            , 1
                            , TRUNC(dbms_random.value(4, 100))), '(.....)', '\1 ')
        , SYSTIMESTAMP);
    COMMIT WORK; 
    END LOOP;
END;


/* compare these queries and notice that the sort order in the first query does not
   conform to the expected order of the IOT composite index (WORK_DATE, EMP_ID) */

    /* Query #1 */
SELECT * FROM EMPLOYEE_HOURS;

    /* Query #2 */
SELECT * FROM EMPLOYEE_HOURS ORDER BY 1, 2;

【问题讨论】:

    标签: oracle ddl composite-primary-key clustered-index tablespace


    【解决方案1】:

    IOT 不保证连续的行存储在连续的块中。它也不保证将按排序顺序检索行。

    在 oracle 中最接近控制行存储方式的是聚簇表。

    现在,我认为您的解决方案存在一些基本问题:

    1. 您声称索引将是检索有序的最佳索引 结果 - 这并不完全正确。索引扫描需要单个 IO 访问,而全扫描可以在一个 IO 中获取多个块。所以 使用索引检索具有 10 个块的表将导致 10 IO 而与multi_block_read_count = 32、FTS 和 哈希排序将需要更多的 CPU,但只需要一个 IO。考虑一下。

    2. 除了执行排序依据之外,没有方法可以保证排序结果。您可能应该在表格顶部声明一个视图并在那里执行排序。

    【讨论】:

      猜你喜欢
      • 2015-06-14
      • 2011-03-13
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-04-27
      • 1970-01-01
      • 2012-10-01
      相关资源
      最近更新 更多