【问题标题】:How can I estimate the size of an Oracle index?如何估计 Oracle 索引的大小?
【发布时间】:2009-05-05 22:06:08
【问题描述】:

我正在考虑向 Oracle 表添加索引,但我想先估计索引构建后的大小(我不需要精确的大小 - 只是一个估计值。)

假设我可以访问有关表的所有元数据(行数、列数、列数据类型等),我可以执行任意 Oracle SQL 查询以获取有关表当前状态的其他数据,并且我知道我希望索引定义是什么,我该如何估计这个大小?

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您可以使用这些Oracle Capacity planning and Sizing Spreadsheets

    对于不太成熟的东西,如果你只是想要回信封类型rough estimates for the index

    计算每个的平均大小 组成索引键的列 并将列加一个 rowid 和 为索引行标题添加 2 个字节 获得平均行大小。现在添加 与 pctfree 的价值相差不大 提出开销的索引 系数,对于 10 的 pctfree 可能是 1.125。

    索引表行数 X 平均行数 长度 X 1.125

    注意 - 如果索引包含可为空的 列然后每个表行可能不会 出现在索引中。在单 列索引,其中 90% 的列 为空只有 10% 会进入 索引。

    将估计值与表空间范围进行比较 分配方法和调整最终 必要时回答。

    另外一个更大的开销因素可能是 指数越大越好 索引的数据越多,分支越多 支持索引所需的块 结构和计算真的 只是叶块的数字。

    【讨论】:

      【解决方案2】:

      您可以通过在 create index 语句上运行 explain plan 来估计索引的大小:

      create table t as
        select rownum r 
        from   dual 
        connect by level <= 1000000;
      
      explain plan for
        create index i on t (r);
      
      select * 
      from   table(dbms_xplan.display(null, null, 'BASIC +NOTE'));
      
      PLAN_TABLE_OUTPUT                                                                                                                         
      --------------------------------------------------------------------------------------------------------------------------------------------
      Plan hash value: 1744693673                                                                                                                 
      
      ---------------------------------------                                                                                                     
      | Id  | Operation              | Name |                                                                                                     
      ---------------------------------------                                                                                                     
      |   0 | CREATE INDEX STATEMENT |      |                                                                                                     
      |   1 |  INDEX BUILD NON UNIQUE| I    |                                                                                                     
      |   2 |   SORT CREATE INDEX    |      |                                                                                                     
      |   3 |    TABLE ACCESS FULL   | T    |                                                                                                     
      ---------------------------------------                                                                                                     
      
      Note                                                                                                                                        
      -----                                                                                                                                       
         - estimated index size: 4194K bytes    
      

      查看底部的“注意”部分:预计索引大小:4194K 字节

      【讨论】:

        【解决方案3】:

        从版本 10gR2 开始,您可以使用 DBMS_SPACE.CREATE_INDEX_COST

        DBMS_SPACE.CREATE_INDEX_COST (
           ddl             IN    VARCHAR2,
           used_bytes      OUT   NUMBER,
           alloc_bytes     OUT   NUMBER,
           plan_table      IN    VARCHAR2 DEFAULT NULL);
        

        来自文档:“此过程确定在现有表上创建索引的成本。输入是将用于创建索引的 DDL 语句。该过程将输出创建索引所需的存储空间。”

        https://docs.oracle.com/database/121/ARPLS/d_space.htm#ARPLS68101

        示例(也位于sqlfiddle):

        DECLARE 
         ub NUMBER; 
         ab NUMBER; 
        BEGIN 
         DBMS_SPACE.CREATE_INDEX_COST (
            ddl             => 'CREATE INDEX x_1 ON t1 (a,b,c) TABLESPACE users',
            used_bytes      => ub,
            alloc_bytes     => ab
           );
         DBMS_OUTPUT.PUT_LINE('Used MBytes: ' || ROUND(ub/1024/1024)); 
         DBMS_OUTPUT.PUT_LINE('Alloc MBytes: ' || ROUND(ab/1024/1024)); 
        END; 
        / 
        

        输出:

        Used MBytes: 1
        Alloc MBytes: 2
        

        【讨论】:

        • 在我需要它仅 8 年后 - 但是,仍然很方便 :)
        【解决方案4】:

        下面的SQL查询可以知道oracle中一个表估计占用的index size

        SELECT (row_size_in_bytes * cnt_of_rows)/1000/1000/1000 index_size_in_GB
        FROM
        (
          SELECT table_name ,
                 (sum (column_length) / 1048576) * 1000000 row_size_in_bytes
          FROM   user_ind_columns
          WHERE  table_name=UPPER('&Enter_Table_Name')
          GROUP  BY table_name
        ) A,
        (SELECT count(1) cnt_of_rows FROM &Enter_Table_Name );
        

        【讨论】:

          猜你喜欢
          • 2010-09-09
          • 2010-09-15
          • 2020-12-24
          • 1970-01-01
          • 1970-01-01
          • 2023-03-21
          • 1970-01-01
          • 2011-03-05
          • 1970-01-01
          相关资源
          最近更新 更多