日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据表创建参数介绍

發布時間:2024/8/26 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据表创建参数介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

創建數據表create table是我們對數據庫進行的常見操作。我們一般使用create table之后,指定了數據列信息和主鍵等約束信息,其他就交給Oracle使用默認值了。今天我們一起來看看這些默認值。說明:本片只關注一般數據表,臨時表、聚簇、IOT等特殊類型暫時不考慮。

?

提取完整的DDL

?

首先我們需要提取出創建數據表的完整DDL語句,才能將Oracle提供的默認值們正確抽取出來。此處我們使用dbms_metadata.get_ddl方法。

//源數據抽取腳本

set serveroutput on size 10000;

set timing on;

?

declare

?c_ddl clob;

begin

?c_ddl := dbms_metadata.get_ddl('TABLE','DEPT','SCOTT');

?

?dbms_output.put_line(c_ddl);

end;

/

//輸出結果

?CREATE TABLE "SCOTT"."DEPT"

??(???"DEPTNO" NUMBER(2,0),

???"DNAME" VARCHAR2(14),

???"LOC" VARCHAR2(13),

????CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO")

?USING INDEXPCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS

?STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

?PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

?TABLESPACE "USERS"?ENABLE

??)

PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

?STORAGE

(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

?PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

?TABLESPACE "USERS"

?

?

上面是使用Oracle自帶的源數據導出工具,對Scott用戶下的數據表EMP進行提取的DDL語句。

?

?

注意:其上有兩個片段(標注紅色)是相似。這個要說明一下,我們建立一個數據表,在Oracle中要建立數據段data?segment對象。同時,如果我們指定了主鍵,Oracle會自動為這個主鍵建立索引,索引是一種索引段index segment對象。所以,如果在建立數據表的時候,也指定了主鍵primary key,那么一共會生成兩個段segment對象。

?

下面,我們對相似的代碼參數片段進行分析。

?

1、PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

2、STORAGE

(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

?PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

3、TABLESPACE "USERS"

?

?

代碼段可以分為三個部分,下面分別進行介紹。

?

Part1、數據塊Data Block與表屬性部分

?

標注1部分表示是數據塊結構和使用參數,以及我們的數據表在使用中的一些參數。

?

在Oracle中,數據庫邏輯結構被劃分為“表空間Tablespace、段對象Segment、分區extent和塊block”。其中,block是最小的結構對象。

?

ü???????PCTFREE:為數據更新準備的“留白”

?

數據終究是要寫入到數據塊里面的。對數據表中的塊block來說,都會依次填滿行數據。而Oracle寫數據表的順序是首先找到一個空閑塊,之后向空閑塊中寫入數據。

?

那么Oracle如何判斷這個數據塊是否非空閑呢?就是使用PCTFREE參數了,該參數是一個百分比值,默認為10%。如果一個數據塊空閑的空間低于PCTFREE設定值,就認為這個數據塊已經寫滿。會將這個塊從空閑塊的列表(FREELIST)上取下來。

?

那么,為什么要有這個參數?為什么要保留這10%呢?答案就是為了進行update使用。數據保存在數據行里,隨著不斷的更新,每行所占有的空間是一個不定的范圍。在數據插入之后,如果發生存儲空間增加(比如:varchar2類型字符長度變化),余下的10%就留作數據行空間延展使用。

?

那么,如果超過這個10%,還是不能裝下數據怎么辦?Oracle定位數據使用的物理rowid機制,實際上就是定位特定的數據行在某個數據塊的第幾個slot(槽)上。如果一個數據塊再也裝不下一些數據行,那么這些數據行就需要另找一個新的數據塊進行保存。也就意味著這些行有一個新的new-rowid位置。但是,Oracle還會按照原來的old-rowid定位數據行。原來的數據塊上,記錄著該數據行的新位置new-rowid,再次找到新的數據行位置。這個技術過程就稱為行遷移(row migrate)。

?

注意:我們要讀一個數據行的內容。理論上希望訪問的數據塊越少越好,最好只有一個塊。但是,如果發生行遷移,我們就不得不訪問多個數據塊才能得到數據。所以,行遷移是我們通常不希望看到的。解決的方法,就是保留一個適當的PCTFREE值。

?

?

選擇合適的PCTFREE的值要根據系統的性質而定。如果是一個典型的OLTP系統,數據更新操作多,變化大。這時候就需要設置一個略大些的PCTFREE。相反,如果更新很少,大部分都是讀操作,PCTFREE略小些也無礙。

?

?

PCTFREE意味著一種空間的閑置。如果需要進行某種數據表壓縮,設置PCTFREE為0也是一種思路。

?

?

ü???????PCTUSED:數據塊的判定容量底線

?

剛才我們談論PCTFREE的時候,介紹了Oracle在寫入數據的時候,是將新數據寫入到數據塊中,直到認為已經滿了后,再尋找新塊寫入。這個過程相反的是,如果一個過去寫滿的數據塊,經過若干次刪除后,會逐漸變空,那么什么時間點才能認為這個塊是一個空閑塊,能接受新的數據插入呢?

?

這就是PCTUSED參數的用途。如果一個數據塊的使用容量低于PCTUSED設置的限制,那么就認為這個數據塊已經空閑,可以放置回FREELIST列表中,作為空閑數據塊接受新數據行的插入。

?

?

一般是不需要調節這個參數的,筆者認為,頻繁的數據塊空閑或者寫滿切換,是有損于數據庫性能的。所以,設置默認的40%一般是可以接受的。對一些數據變化巨大,刪除頻繁的系統,這個參數可以配合PCTFREE統一籌劃。

?

?

ü???????INITRANS和MAXTRANS

?

初始事務INITRANS和最大事務MAXTRANS是在數據塊級別的參數。Oracle行級鎖是Oracle最大的特點之一。數據庫事務的本質還是對數據塊的修改,而事務的信息是記錄在數據塊頭。

?

參數INITRANS的作用就是表示數據塊上可以標記的初始事務數目。如果同時進行的事務數據量超過這個數量,事務數目可以增加,直到達到MAXTRANS的限制。

?

?

從性能角度看,我們不希望一個數據塊同時進行過多的事務。因為這樣起碼意味著數據塊過熱。所以,建議設置一個合理的INITRANS。

?

ü???????COMPRESS壓縮參數

?

Compress參數含義很清楚:就是在存儲數據表數據的時候是否啟用壓縮選項。壓縮使用的級別是數據塊block級別。Oracle對數據塊的壓縮采用相鄰相同值合并的壓縮算法。

?

Compress參數有兩個系列參數:

?

1、OMPRESS FOR DIRECT_LOAD OPERATIONS:作用于Compress相同,適合于數據倉庫OLAP系統。只在直接插入過程中在表或者分區上啟用壓縮技術

2、COMPRESS FOR ALL OPERATIONS:適合于OLTP系統,針對所有的操作均啟用了壓縮選項。要求的版本較高。

?

下面,我們通過一個小實驗,來確定壓縮效果。首先,構建兩個數據表test和test1,數據量和順序相同,只是參數不同。

?

SQL> conn scott/tiger@orcl;

Connected to Oracle Database?10g?Enterprise Edition Release 10.2.0.1.0

Connected as scott

?

SQL> set timing on;

SQL> create table testnocompressas select * from all_objects where 1=0;

Table created

Executed in 0.11 seconds

?

SQL> insert /*+append */ into test select * from all_objects;

40724 rows inserted

(提交和重復執行該語句,篇幅原因省略

?

SQL> insert into test?select * from test;

122170 rows inserted

Executed in 8.412 seconds

?

SQL> select count(*) from test;

?COUNT(*)

----------

???244340

Executed in 0.872 seconds

?

SQL> exec dbms_stats.gather_table_stats('SCOTT','TEST',cascade => true);

PL/SQL procedure successfully completed

Executed in 2.354 seconds

?

//壓縮數據表

SQL> create table test1compressas select * from all_objects where 1=0;

Table created

Executed in 0.17 seconds

?

SQL> insert /*+append */ into test1 select * from all_objects;

40724 rows inserted

Executed in 2.724 seconds

(提交和重復執行該語句,篇幅原因省略

?

SQL> insert into test1?select * from test1;

122172 rows inserted

Executed in 1.562 seconds

?

SQL> commit;

Commit complete

Executed in 0.03 seconds

SQL> select count(*) from test1;

?

?COUNT(*)

----------

???244344

?

Executed in 0.03 seconds

?

SQL> exec dbms_stats.gather_table_stats('SCOTT','TEST1',cascade => true);

?

PL/SQL procedure successfully completed

?

Executed in 0.501 seconds

?

?

兩個數據表數據量和結構完全相同,內容也相同。經過分析后,我們檢查數據字典反應的情況。

?

SQL> select segment_name, segment_type, bytes/1024/1024 MB, blocks, extents from user_segments where?segment_name in ('TEST','TEST1');

?

SEGMENT_NA SEGMENT_TY????????MB????BLOCKS???EXTENTS

---------- ---------- ---------- ---------- ----------

TEST1?????TABLE?????????????17??????2176????????32

TEST??????TABLE?????????????28??????3584????????43

?

Executed in 0.08 seconds

?

?

結果很清楚了,在沒有使用壓縮技術的TEST數據表,占有空間28MB,共3584個數據塊。而采用過數據庫壓縮技術后,空間使用到了17MB,共2176個數據塊,空間節省39%左右。

?

進一步實驗,根據Oracle壓縮的方法,我們嘗試將近似的行之間相同數據情況增加。all_objects視圖中,owner和object_type相似度較高,選擇性低,這樣我們組織數據形態。

?

//構建實驗數據表三

SQL> create table test2 compress as select * from test1order by owner,object_type;

?

Table created

Executed in 5.719 seconds

?

SQL> exec dbms_stats.gather_table_stats(user,'TEST2',cascade => true);

?

PL/SQL procedure successfully completed

Executed in 1.102 seconds

?

SQL> select segment_name, segment_type, bytes/1024/1024 MB, blocks, extents from user_segments where?segment_name in ('TEST','TEST1','TEST2');

?

SEGMENT_NA SEGMENT_TY????????MB????BLOCKS???EXTENTS

---------- ---------- ---------- ---------- ----------

TEST1?????TABLE?????????????17??????2176????????32

TEST??????TABLE?????????????28??????3584????????43

TEST2?????TABLE?????????????10??????1280????????25

?

Executed in 0.08 seconds

?

?

按照算法特征進行整理之后,數據表大小便為了10M,壓縮率提高到了64%。

?

ü???????LOGGING:日志記錄

LOGGING參數表示對數據表或者其他對象進行變化性操作的時候,是否計入到REDO日志中。默認情況下,Oracle對數據庫對象的任何修改性操作都會計入到redo log中,作為數據庫恢復使用。開啟logging功能,是保證數據庫數據一致性的重要一步。

?

有一些時候,我們可能會不希望記日志操作。因為logging的時候會存在相當的性能損失,為了避免這種損失,加快操作速度,我們可能會選擇暫時性的設置數據表為nologging狀態。比如,我們在進行大規模數據加載的時候,可能就會選擇這種方式。

?

?

先不論nologging的好壞,有幾個問題筆者需要說明。首先,啟用數據表的nologging絕不意味著說一點重做日志都不書寫。在運行過程中,數據表對應的索引對象等內容,都有一個重建的過程,這個過程是需要寫入redo log的。第二,不啟用redo log,的確會帶來一定的性能提升。但是沒有日志的數據庫是極其危險的,一旦發生實例崩潰或者數據庫崩潰這種情況,數據庫數據丟失和不一致的情況是可能發生的。這種方法得不償失。


總結

以上是生活随笔為你收集整理的数据表创建参数介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。