分區是一把雙刃劍 要分區絕對要根據實際狀況來分析 而我所遇到的狀況及時最利於分區的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;.....
分區後日志查詢速度快的不是通常多啊 !!