不准確分析及規避方法
1 案例回訪
硬件環境:IBM XSERIES 3650
操作系統:Windows2003標准版+Sp02
數據庫版本:Oracle9.2.0.1
PL/SQL Developer版本:7.0.2.1076
由於業務需要,需先drop一張分區表T_SMS,再重建此表,要求表結構、索引等完全一致。但當時開局版本一時無法找到,故決定利用PL/SQL Developer工具“VIEw SQL”獲取到的SQL語句來重建分區表。(此分區表按天進行分區,且由於每天數據量龐大,故每天凌晨都會truncate上個月的數據,保證表中最多只保留30天數據。)
重建表後第二天發現此表索引失效,導致無法進行insert等操作。經過分析,truncate分區操作最可能造成索引失效。但此表建立的是本地分區索引,按天truncate操作後,Oracle會自動重建本地分區索引,不應該需要手工干預,且以前此表沒有出現過索引失效的問題。故初步判斷可能是新舊表結構不同造成,立即查看此表索引類型,發現索引並不是本地索引,且從PL/SQL Developer工具中導出的建索引語句中也並不是本地索引。
那為何原表索引為本地分區索引,利用PL/SQL Developer工具導出腳本後索引類型就改變了呢?是不是PL/SQL Developer工具在導出索引腳本方面存在bug?
2 案例分析
剛才已經通過查看當時建表語句即可定位為PL/SQL Developer工具導出的腳本問題,我們可以再通過以下幾個試驗來驗證一下。
2.1 建索引時加local關鍵字
(1)建索引語句如下:
create index T_SMS_IDMONTHDAY on T_SMS (MONTHDAY)
local tablespace SMS_DAT;
(2)利用PL/SQL Developer工具“VIEw SQL”獲取的建索引腳本如下:
create index T_SMS_IDMONTHDAY on T_SMS (MONTHDAY);
(3)分析:
可見,建本地分區索引後再利用PL/SQL Developer工具導出腳本即變為了全局索引,索引類型發生了變化。
2.2 建索引時不加local關鍵字或加global關鍵字
(1)建索引語句如下:
create index T_SMS_IDMONTHDAY on T_SMS (MONTHDAY)
[global] tablespace SMS_DAT;
(2)利用PL/SQL Developer工具“VIEw SQL”獲取的建索引腳本如下:
createindexT_SMS_IDMONTHDAYonT_SMS(MONTHDAY)
tablespaceSMS_DAT
pctfree10
initrans2
maxtrans255
storage
(
initial64K
minextents1
maxextentsunlimited
);
(3)分析:
可見,建索引時無論不加local關鍵字還是加global關鍵字再利用PL/SQL Developer工具導出的腳本都變為了全局索引,同時多了些存儲相關的選項。
2.3 分別利用PL/SQL Developer 工具的“Oracle Export”、“SQL Insert”、“PL/SQL Developer”三種方式導出
通過導出後再導入的方式來驗證,只有“Oracle Export”方式導出再導入後,表結構和索引結構沒有發生變化,另兩種方式都改變了索引類型。
3 規避方法介紹
從上述對比試驗中可以看出,只有Oracle自帶的Export命令導出再導入後的索引結構和原有結構一致,其他方式都無法准確獲取到分區索引的腳本。
雖然我們可以通過把Export導出條件設置為不存在結果集來導出空表,再利用導出的dump文件導入到其他庫來新建表和索引。但這種方式無法直觀的看到建表的SQL腳本,可擴展性差。
本地索引:
CREATE INDEX T_SMS_IDMONTHDAY ON T_SMS
(MONTHDAY)
TABLESPACE SMS_DAT
INITRANS 2
MAXTRANS 255
LOCAL (
PARTITION P01
LOGGING
NOCOMPRESS
TABLESPACE SMS_DAT
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS 2147483645
BUFFER_POOL DEFAULT
),
PARTITION P02
LOGGING
NOCOMPRESS
TABLESPACE SMS_DAT
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS 2147483645
BUFFER_POOL DEFAULT
)
……(此處省略部分代碼)
)
NOPARALLEL;
全局索引:
CREATE INDEX T_SMS_IDMONTHDAY ON T_SMS
(MONTHDAY)
LOGGING
TABLESPACE SMS_DAT
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS 2147483645
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
NOPARALLEL;