oracle 11g表智能按月分區

分區是一把雙刃劍 要分區絕對要根據實際狀況來分析 而我所遇到的狀況及時最利於分區的sql

sql編程的藝術 做者說過 「對分區表進行查詢,當數據按分區鍵均勻分佈時,受益最大。」編程

 

而我採用的分區鍵是日子表的日誌插入時間 按照一個月分一區,由於這個表每月都有基本平衡的頻率的數據插入, 這樣表中的全部數據就能夠均勻的分佈到每一區。oracle

 

使人激動的一天不算以前的學習研究 這個就花了我一下午less

以前日誌表700多萬數據,涉及到日誌表的業務查詢速度很慢一個月的數據查詢也將近30秒左右,研究發現oracle有表分區功能 11G更加有智能按月分區功能 開幹:學習

前提確認能的表能夠分區測試

第一步,先建立分區的表spa

--INTERVAL分區
--這個實際上是範圍分區的加強功能,經過這個功能能夠實如今須要的時候自動的實現新的分區的添加,從而省去了你不斷的ADD或者SPLIT新的分區。日誌

CREATE TABLE SYS_LOG_TEM(pid            NUMBER not null,
  yhdm           VARCHAR2(30),
  bmdm           VARCHAR2(12),
  pdaid          VARCHAR2(512),
  simid          VARCHAR2(50),
  logmodule      VARCHAR2(1),
  logtype        VARCHAR2(4),
  operatetype    CHAR(1),
  methodname     VARCHAR2(100),
  methodinfo     VARCHAR2(2000),
  execstatus     VARCHAR2(1),
  execerrorinfo  VARCHAR2(1000),
  alltimespent   NUMBER,
  proxytimespent NUMBER,
  logcontent     VARCHAR2(4000),
  logtime        DATE default sysdate,
  memo           VARCHAR2(200),
  returnflag     CHAR(1),
  returninfo     VARCHAR2(1000),
  gpsx           VARCHAR2(20),
  gpsy           VARCHAR2(20))
  PARTITION BY RANGE (logtime)
  INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))
  (PARTITION P1 VALUES LESS THAN (TO_DATE('2012-4-1', 'YYYY-MM-DD')));索引

 

(由於我表裏目前的數據最小的是4月份的,因此我讓它從四月份開始分區)it

 

第二步,把老的日誌表的數據插入到新建的分區表  insert into SYS_LOG_TEM   select * from SYS_LOG;

  insert into SYS_LOG_TEM
  select pid,
         yhdm,
         bmdm,
         pdaid,
         simid,
         logmodule,
         logtype,
         operatetype,
         methodname,
         methodinfo,
         execstatus,
         execerrorinfo,
         alltimespent,
         proxytimespent,
         logcontent,
         nvl(logtime,to_date('2008-06-01 00:00:00','yyyy-MM-dd HH24:mi:ss')),
         memo,
         returnflag,
         returninfo,
         gpsx,
         gpsy
    from SYS_LOG;

 

 

數據7272844條 總共花了我7分鐘多

 

這裏之因此對logtim字段作null處理是由於一旦oracle 表作的按月分區就不能讓時間字段爲null不然 更新的時候會報錯 ora-14402 更新分區關鍵字列將致使分區的更改
update sys_log_tem set logtime=null where logtime=to_date('2008-06-01 00:00:00','yyyy-MM-dd HH24:mi:ss'),不知道有沒有別的辦法解決這個問題,不過我這樣作應該也能夠本身取一個自定義時間也是說得過去的

 

 

通過plsql上的測試

查詢速度對比

--作了按每個月分區的表查詢 執行時間 :0.468秒
select count(pid) from ( select  sysLog.pid,sysLog.yhdm,sysLog.operateType,sysLog.methodName,
sysLog.pdaId,sysLog.simId,sysLog.logContent,sysLog.logModule,sysLog.logTime from sys_log_tem sysLog,
Acl_User u where sysLog.yhdm(+)=u.yhdm  and sysLog.logTime>=to_date('2012-06-01 15:48:03','yyyy-mm-dd HH24:MI:SS')
 and sysLog.logTime<=to_date('2012-06-30 15:48:11','yyyy-mm-dd HH24:MI:SS'))

 --這是沒有作分區的表查詢   執行時間 :18秒
 select count(pid) from ( select  sysLog.pid,sysLog.yhdm,sysLog.operateType,sysLog.methodName,
sysLog.pdaId,sysLog.simId,sysLog.logContent,sysLog.logModule,sysLog.logTime from Sys_Log sysLog,
Acl_User u where sysLog.yhdm(+)=u.yhdm  and sysLog.logTime>=to_date('2012-06-01 15:48:03','yyyy-mm-dd HH24:MI:SS')
 and sysLog.logTime<=to_date('2012-06-30 15:48:11','yyyy-mm-dd HH24:MI:SS'))

 

有一個說下新建的分區表我只建了 主鍵 其餘都沒弄 由於我發現再建日期索引的話查詢速度慢了n多,比老表的速度還要慢,不知道這是什麼緣由,反正我新建的表就弄了一個主鍵,view sql的結構是這樣的:

-- Create table
create table SYS_LOG
(
  pid            NUMBER not null,
  yhdm           VARCHAR2(30),
  bmdm           VARCHAR2(12),
  pdaid          VARCHAR2(512),
  simid          VARCHAR2(50),
  logmodule      VARCHAR2(1),
  logtype        VARCHAR2(4),
  operatetype    CHAR(1),
  methodname     VARCHAR2(100),
  methodinfo     VARCHAR2(2000),
  execstatus     VARCHAR2(1),
  execerrorinfo  VARCHAR2(1000),
  alltimespent   NUMBER,
  proxytimespent NUMBER,
  logcontent     VARCHAR2(4000),
  logtime        DATE default sysdate,
  memo           VARCHAR2(200),
  returnflag     CHAR(1),
  returninfo     VARCHAR2(1000),
  gpsx           VARCHAR2(20),
  gpsy           VARCHAR2(20)
)
partition by range (LOGTIME)
(
  partition P1 values less than (TO_DATE(' 2012-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    ),
  partition SYS_P22 values less than (TO_DATE(' 2012-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    ),
  partition SYS_P23 values less than (TO_DATE(' 2012-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    ),
  partition SYS_P24 values less than (TO_DATE(' 2012-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    ),
  partition SYS_P25 values less than (TO_DATE(' 2012-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    ),
  partition SYS_P26 values less than (TO_DATE(' 2012-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    ),
  partition SYS_P27 values less than (TO_DATE(' 2012-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    ),
  partition SYS_P28 values less than (TO_DATE(' 2012-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    ),
  partition SYS_P29 values less than (TO_DATE(' 2012-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
    tablespace SYSTEM
    pctfree 10
    pctused 40
    initrans 1
    maxtrans 255
    storage
    (
      initial 64K
      next 1M
      minextents 1
      maxextents unlimited
    )
);
-- Create/Recreate primary, unique and foreign key constraints
alter table SYS_LOG
  add constraint PID primary key (PID)
  using index
  tablespace SYSTEM
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );

 

11g分區表按時間自動建立(Interval Partitioning) 我這個用到了oracle 11G的新特性

INTERVAL分區
這個實際上是範圍分區的加強功能,經過這個功能能夠實如今須要的時候自動的實現新的分區的添加,從而省去了你不斷的ADD或者SPLIT新的分區。

若是是9i的話 必須把分區的日期寫死 根據你的表裏的日誌值,由於日誌表在實時增長數據,你還得按期去手動新建 新的分區,好比這樣alter table sys_log_tem add PARTITION logtime values less than('2012-06-01 00:00:00') tablespace system;.....

 

分區後日志查詢速度快的不是通常多啊  !!

相關文章
相關標籤/搜索