程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> EDB和Oracle在分區剪裁實踐上的一點差別

EDB和Oracle在分區剪裁實踐上的一點差別

編輯:Oracle教程

EDB和Oracle在分區剪裁實踐上的一點差別


前兩天碰到一個問題,在EDB數據庫中創建的一張分區表,需要使用分區本地索引和分區剪裁,但查看執行計劃發現沒能用到分區剪裁的功能。

創建分區表:

CREATE TABLE test
(
  id bigint NOT NULL,
  bag_id bigint,
  bp_airline_code character varying(3),
  bp_flight character varying(5),
  bp_flight_suffix character varying(2),
  bp_flight_date timestamp with time zone,
  CONSTRAINT pk_test PRIMARY KEY (id)
)
partition by range(bp_flight_date)
(
    partition part_20151101 VALUES LESS THAN('2015-NOV-02'),
    partition part_20151102 VALUES LESS THAN('2015-NOV-03'),
    partition part_20151103 VALUES LESS THAN('2015-NOV-04')
);

創建主表和三個分區的本地索引:

CREATE INDEX test_idx_01
    ON test
    (bag_id, bp_airline_code, bp_flight, bp_flight_suffix);

CREATE INDEX test_part_20151101_idx
    ON test_part_20151101
    (bag_id, bp_airline_code, bp_flight, bp_flight_suffix);

CREATE INDEX test_part_20151102_idx
    ON test_part_20151102
    (bag_id, bp_airline_code, bp_flight, bp_flight_suffix);

CREATE INDEX test_part_20151103_idx
    ON test_part_20151103
    (bag_id, bp_airline_code, bp_flight, bp_flight_suffix);

執行以下帶有分區鍵的查詢語句,:

explain select * from test
where bp_flight_date=to_date('2015-11-01', 'yyyy-mm-dd') and bag_id = 1

發現並沒有使用到分區剪裁:
這裡寫圖片描述

有點疑惑,明明用了分區鍵作為查詢條件,為什麼此處是掃描了所有分區?

分析
其實這個問題說簡單也簡單,說麻煩也麻煩,主要還是細節和原理的理解。
上例中使用的分區規則是:

partition by range(bp_flight_date)
(
    partition part_20151101 VALUES LESS THAN('2015-NOV-02')
...

以bp_flight_date日期字段作為分區鍵,條件是LESS THAN(‘2015-NOV-02’)。但執行的查詢語句條件是:

where bp_flight_date=to_date('2015-11-01', 'yyyy-mm-dd') and bag_id = 1

對日期值是使用了to_date函數,並不是像分區規則中的“字符串”格式,有理由懷疑是因為兩者不統一,由於某些RULE導致未能用到分區剪裁的功能。

接下來按照猜想改下查詢條件:

explain select * from test
where bp_flight_date='2015-11-01', 'yyyy-mm-dd' and bag_id = 1

查看執行計劃:
這裡寫圖片描述vcHLt9bH+Lz0ssO1xMS/tcShozwvcD4KCjxwPtauy/nS1NPQyc/D5tXi0KnOyszio6y/ycTcu7nKx9S009pPcmFjbGW1xNK70KnLvM6so6zU2k9yYWNsZaOs0uLKtrWx1tC9q8jVxtrX1rbO1/fOqrLp0a/M9bz+vs3TprjDyrnTw3RvX2RhdGUoKdXiwOC1xLqvyv08L3A+Cgo8cD66zcnPw+bP4M2stcSx7b3hubnU2k9yYWNsZdbQtcTKtc/Wo7ogPGJyPgo8aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20151130/201511300932566.png" alt="這裡寫圖片描述" title="\">

這裡寫圖片描述
這裡看到執行計劃顯示還是用到了分區特性,並沒有執行全表掃描,其中Pstart和Pstop顯示的是KEY,表示是基於函數值的分區鍵。

那麼像EDB這樣創建一個不用to_date函數的分區表:
這裡寫圖片描述Oracle的一點不同。

總結
1. EDB中分區鍵是日期字段,VALUES LESS THAN(‘2015-11-01’)可以使用字符串格式,但Oracle則會報ORA-01861的錯誤,不支持這種創建方式。
2. EDB對使用分區鍵的查詢語句,如果日期條件的格式和分區規則中不同,例如分區規則是’2015-NOV-01’或’2015-11-01’,但查詢條件使用to_date(‘2015-11-01’,’yyyy-mm-dd’),則不會用到分區剪裁的特性,而是掃描所有分區。對於Oracle,在創建分區規則時就已經做了嚴格限制,因此不存在日期條件的格式和分區規則中不一致的情況。這兩種方式說不上孰好孰壞,EDB是更自由,但需要人為注意書寫的正確,Oracle則是嚴謹,好處是避免了人為使用出錯的可能,間接上可能也反映出了“社區 VS 商業”、“開源 VS 閉源”對待某個問題的一種態度。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved