平台2.0索引重建

平台2.0索引重建

背景:平台2.0数据库在各地应用有很长一段时间了,索引对数据库查询速度的影响是非常关键的,经分析,目前平台2.0数据库索引主要存在两方面问题:

1、各地平台数据库表结构基本保持一致,但索引的命名规范,创建时间可能各地都不一致(因上线时间不一致),导致无法保证数据库基本结构的一致;

2、随着上线时间的累积,各地数据量大,也没有专职DBA做数据库日常优化,数据增、删比较频繁,导致索引产生碎片,性能下降,并占用空间不能有效释放。

当前各地上线平台已经存储了客户的业务数据内容,对数据库的更新我们必须认真分析和严格测试才能在正式库上更新,针对以上两个问题,我们分别制定了不同的解放方案。

一、       索引的统一和升级

备注:

1、这个过程只在第一次升级时执行一次即可,这个执行过程会长一些,需要认真比对和检查;

2、索引库和创建索引表务必从测试后的标准库统一导出建立,以下流程完成后形成文件XT_INDEXTAB.SQLCREATINDEX.SQLDROPINDEX.SQL作为升级使用。

第一步:索引库准备

--创建标准索引表

-- CREATE TABLE

CREATE TABLE XT_INDEXTAB

(

  TABLE_NAME VARCHAR2(100),

  INDEX_NAME VARCHAR2(200),

  INDEX_TYPE CHAR(1)

);

-- ADD COMMENTS TO THE TABLE

COMMENT ON TABLE XT_INDEXTAB

  IS '索引表';

-- ADD COMMENTS TO THE COLUMNS

COMMENT ON COLUMN XT_INDEXTAB.TABLE_NAME

  IS '表名';

COMMENT ON COLUMN XT_INDEXTAB.INDEX_NAME

  IS '索引名';

COMMENT ON COLUMN XT_INDEXTAB.INDEX_TYPE

  IS '索引类型';

--将主键索引到入到标准索引库

INSERT INTO XT_INDEXTAB

  (TABLE_NAME, INDEX_NAME,INDEX_TYPE)

  SELECT AU.TABLE_NAME ASTABLE_NAME,

         AU.INDEX_NAME ASINDEX_NAME,

         '0' AS INDEX_TYPE 

    FROM USER_CONSTRAINTS AU

   WHERE AU.CONSTRAINT_TYPE = 'P'

     AND AU.INDEX_OWNER ='HEALTH_BASE'--注意更换用户名

--将非主键索引到入到标准索引库

INSERT INTO XT_INDEXTAB

  (TABLE_NAME, INDEX_NAME,INDEX_TYPE)

  SELECT IU.TABLE_NAME ASTABLE_NAME,

         IU.INDEX_NAME ASINDEX_NAME,

         '1' AS INDEX_TYPE

    FROM USER_INDEXES IU

   WHERE IU.INDEX_NAME NOT IN

         (SELECT AU.INDEX_NAME

            FROM USER_CONSTRAINTSAU

           WHEREAU.CONSTRAINT_TYPE = 'P'

             AND AU.INDEX_OWNER ='HEALTH_BASE') --注意更换用户名

     AND IU.INDEX_TYPE = 'NORMAL'

     AND IU.TABLE_OWNER ='HEALTH_BASE' --注意更换用户名

--导出标准索引库:XT_INDEXTAB.SQL

insert into XT_INDEXTAB (TABLE_NAME, INDEX_NAME, INDEX_TYPE)

values ('HRB0309', 'HRB0309_PK', '0');

insert into XT_INDEXTAB (TABLE_NAME, INDEX_NAME, INDEX_TYPE)

values ('HRB0310', 'HRB0310_PK', '0');

insert into XT_INDEXTAB (TABLE_NAME, INDEX_NAME, INDEX_TYPE)

values ('HRB0311', 'HRB0311_PK', '0');

insert into XT_INDEXTAB (TABLE_NAME, INDEX_NAME, INDEX_TYPE)

values ('HRB0399_01_02', 'HRB0399_01_02_PK', '0');

insert into XT_INDEXTAB (TABLE_NAME, INDEX_NAME, INDEX_TYPE)

values ('HRB0399_01_04', 'HRB0399_01_04_PK', '0');

--创建非主键索引文件:CREATINDEX.SQL;

-- CREATE/RECREATE INDEXES

CREATE INDEX I_HRA00_01_01_HR99_02_001 ON HRA00_01_01 (HR42_02_002,HR99_99_007, HR99_02_001)

  TABLESPACE HEALTH_BASE

  PCTFREE 10

  INITRANS 2

  MAXTRANS 255

  STORAGE

  (

    INITIAL 49M

    MINEXTENTS 1

    MAXEXTENTS UNLIMITED

  );

CREATE INDEX LDX_ZDYDAH ON HRA00_01_01 (ZDYJKDAH)

  TABLESPACE HEALTH_BASE

  PCTFREE 10

  INITRANS 2

  MAXTRANS 255

  STORAGE

  (

    INITIAL 31M

    MINEXTENTS 1

    MAXEXTENTS UNLIMITED

  );

………

第二步:索引库比对

--查询全部主键索引 与标准主键索引库对比是否一致;

SELECT AU.TABLE_NAME AS 表名, AU.INDEX_NAME AS 主键索引名

  FROM USER_CONSTRAINTS AU

 WHERE AU.CONSTRAINT_TYPE = 'P'

   AND AU.INDEX_OWNER ='HEALTH_BASE'

 ORDER BY AU.TABLE_NAME

--如果不一致,逐一修改主键索引;

--查询全部非主键索引库,对比非数据索引与标准库是否一致;

SELECT IU.TABLE_NAME AS 表名, IU.INDEX_NAME AS 非主键索引名

  FROM USER_INDEXES IU

 WHERE IU.INDEX_NAME NOT IN

       (SELECT AU.INDEX_NAME

          FROM USER_CONSTRAINTSAU

         WHERE AU.CONSTRAINT_TYPE= 'P'

           AND AU.INDEX_OWNER ='HEALTH_BASE') --注意更换用户名

   AND IU.INDEX_TYPE = 'NORMAL'

   AND IU.TABLE_OWNER ='HEALTH_BASE'    --注意更换用户名

 ORDER BY IU.TABLE_NAME

第三步:索引库删除

--如果不一致,删除全部非主键索引;

SELECT 'DROP INDEX ' || IU.INDEX_NAME || ';'

  FROM USER_INDEXES IU

 WHERE IU.INDEX_NAME NOT IN

       (SELECT AU.INDEX_NAME

          FROM USER_CONSTRAINTSAU

         WHERE AU.CONSTRAINT_TYPE= 'P'

           AND AU.INDEX_OWNER ='HEALTH_BASE') --注意更换用户名

   AND IU.INDEX_TYPE = 'NORMAL'

   AND IU.TABLE_OWNER ='HEALTH_BASE' --注意更换用户名

 ORDER BY IU.TABLE_NAME

--执行以上查询语句另存为 DROPINDEX.SQL

DROP INDEX INX_OLDDAH;

DROP INDEX INX_NEWDAH;

DROP INDEX STU_NAME_EMAIL_UNI;

DROP INDEX UK_GLVCH;

DROP INDEX LDX_ZDYDAH;

DROP INDEX I_HRA00_01_01_HR99_02_001;

DROP INDEX DAH_UN;

DROP INDEX ZDYDAH;

DROP INDEX INX9901004_HRA99_01_01;

--执行索引删除脚本:DROPINDEX.SQL

第三步:标准索引库创建

执行创建索引脚本:CREATINDEX.SQL

第四步:同第二步,再次检查主键索引和非主键索引建立情况,直到索引与标准索引库一致;

二、       索引的定时重建

备注:

1、 这个过程可定时执行,可以每隔30天执行一次

2、 这个执行完后生成索引重建日志。

第一步:创建索引重建日志记录表:

-- CREATE TABLE

CREATE TABLE XT_INDEXLOG

(

  REBUILDDATE  CHAR(19),

  REBUILDSTATE CHAR(1),

  REBUILDLOG   VARCHAR2(1024)

);

-- ADD COMMENTS TO THE TABLE

COMMENT ON TABLE XT_INDEXLOG

  IS '索引日志表';

-- ADD COMMENTS TO THE COLUMNS

COMMENT ON COLUMN XT_INDEXLOG.REBUILDDATE

  IS '重建日期';

COMMENT ON COLUMN XT_INDEXLOG.REBUILDSTATE

  IS '重建结果 0 -成功,1-失败';

COMMENT ON COLUMN XT_INDEXLOG.REBUILDLOG

  IS '重建信息';

第二步:定义索引重建存储过程

CREATE OR REPLACE PROCEDURE REBUILD_INDEX AS

/*全部索引重建*/

  CURSOR INDEXCURSOR IS

    SELECT *

      FROM USER_INDEXES

     WHERE TABLE_OWNER ='HEALTH_BASE'--根据用户名修改

       AND INDEX_TYPE = 'NORMAL';

  INDEXROW INDEXCURSOR %ROWTYPE;

  SQLTEXT  VARCHAR2(1024);

BEGIN

  OPEN INDEXCURSOR;

  LOOP

    FETCH INDEXCURSOR INTOINDEXROW;

    EXIT WHEN INDEXCURSOR%NOTFOUND;

    SQLTEXT := ' ALTER INDEX ' ||INDEXROW . INDEX_NAME || ' REBUILD ';

    BEGIN

      EXECUTE IMMEDIATE(SQLTEXT);

      INSERT INTO XT_INDEXLOG

       (REBUILDDATE,REBUILDSTATE, REBUILDLOG )

      VALUES

        (SYSDATE, '0', 'REBUILDINDEX SUCCESS:' || INDEXROW . INDEX_NAME);

    EXCEPTION

      WHEN OTHERS THEN

        INSERT INTO XT_INDEXLOG

         (REBUILDDATE,REBUILDSTATE, REBUILDLOG )

        VALUES

          (SYSDATE, '1', 'REBUILDINDEX FAIL:' || INDEXROW . INDEX_NAME);

    END;

  END LOOP;

END;

第三步:索引重建定时执行

DECLARE

  JOB NUMBER; --每月定时执行

BEGIN

  SYS .DBMS_JOB.SUBMIT(JOB       => JOB,

                       WHAT      => 'REBUILD_INDEX;',

                       NEXT_DATE=> TRUNC(SYSDATE + 30),

                      INTERVAL  => 'TRUNC(SYSDATE +30)',

                       NO_PARSE  => FALSE);

END;

第四步:定期检查索引重建日志。

原文地址:https://www.cnblogs.com/zlchust/p/11739811.html