亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解Oracle聚簇Cluster

發布時間:2021-11-08 18:37:57 來源:億速云 閱讀:134 作者:柒染 欄目:建站服務器

如何理解Oracle聚簇Cluster,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

Oracle數據表三種基本類型:堆表Heap Table、索引組織表IOT和聚簇表Cluster。在我們日常中,最常用也是適應性最好的一種數據表就是堆表Heap Table。一般在沒有特殊性能缺陷和特性要求的情況下,堆表是我們首先的選項。

IOT是一種融合數據到索引結構上的數據表類型。在筆者之前的文章中,詳細介紹了IOT的結構、特性和適應場景,同時也對段溢出Segment Overflow、邏輯Rowid和Secondary Index等概念進行過闡述。

我們介紹一下聚簇。

 

1、概說聚簇Cluster

 

應該說,三種數據表類型中,我們最不常用的結構應該是聚簇。聚簇也是和其他兩種數據表差異最大的一種結構類型,最大的區別在于:聚簇是可以單獨存在的。

 

在Oracle存儲結構中,我們必須遵循兩個概念就是對象和段Segment。我們可以創建很多對象,比如數據表、索引、視圖,但是并不是每個對象都會“真刀真槍”的占用存儲空間。Oracle空間分配是依據邏輯表空間、段對象、分區和塊。只有數據表、索引等對象,才是可以真正使用空間的,分配Segment的。

 

堆表和索引組織表雖然有差別,但是本質上是類似的。堆表中,索引和數據表是分別的數據段結構,索引段和數據表段保持一致性。而IOT實現了索引和數據表段的合一。數據表的所有內容,依據主鍵順序被保存在IOT索引樹的葉子節點上。由于數據表內容的特殊性,比如字段過大的情況,都是通過溢出段實現。

 

而Cluster完全不同,Cluster是一種單獨的段結構,或者筆者理解為單獨的段空間容器。在沒有數據表和索引的時候,Cluster段是可以單獨存在的。依據一定的規則,如連接鍵(Join Key),可以將多個數據表數據保存在同一個段中。并且依據一定場景實現快速檢索連接。

 

我們為什么使用Cluster數據表。最常見的解釋是減少關聯檢索時候進行IO的數量。傳統的數據表結構,兩個表連接,至少要進行兩次數據塊的檢索。而Cluster過程,由于都是存儲在一起(注意:相同Segment)。

 

Cluster進行使用的時候,有兩個類型進行選擇,分別為B樹Cluster和哈希Hash Cluster。兩者既有相同的結構,又有細微的差異。

 

2、實驗環境介紹

 

我們選擇Oracle 11gR2進行實驗。

 

SQL> select * from v$version;

BANNER

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

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production

PL/SQL Release 11.2.0.3.0 - Production

CORE    11.2.0.3.0  Production

TNS for Linux: Version 11.2.0.3.0 - Production

NLSRTL Version 11.2.0.3.0 – Production

 

創建專門的用戶進行實驗。

 

SQL> create user test identified by test default tablespace users;

User created

SQL> grant resource, connect to test;

Grant succeeded

SQL> grant create cluster to test;

Grant succeeded

SQL> grant select any table to test;

Grant succeeded

SQL> grant select any dictionary to test;

Grant succeeded

 

3、B樹Cluster實驗

 

通過一系列的實驗,我們來探討發現Cluster數據表的特性和使用。Oracle Cluster不是隨任何數據表對象創建,而是可以通過SQL語句create cluster來進行創建。

 

SQL> create cluster emp_dept (deptno number) size 600;

Cluster created

SQL> select cluster_name, tablespace_name, cluster_type, key_size from user_clusters;

CLUSTER_NAME          TABLESPACE_NAME              CLUSTER_TYPE   KEY_SIZE

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

EMP_DEPT                       USERS                   INDEX               600

 

注意兩個問題,一個是創建cluster的過程中我們指定的size 600。這個是用于指定cluster鍵大致大小,指定之后,就可以實現空間的預留。如果這個取值設置不合理,容易引起Cluster結構的混亂。

 

另一個問題是tablespace_name,Cluster對象既然包括了tablespace信息,就必然是占用空間的,也必然以segment的形式出現。

 

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name='EMP_DEPT';

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

CLUSTER                     1           4          522      65536          8

 

注意:此時我們沒有創建數據表或者索引,但是cluster segment已經存在出現。下面我們依托cluster emp_dept創建數據表。

 

SQL> create table emp (empno number, empname varchar2(10), deptno number) cluster emp_dept(deptno);

Table created

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name='EMP_DEPT';

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

CLUSTER                     1           4          522      65536          8

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name='EMP';

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

 

依托cluster創建數據表的時候,要指定出哪個字段是cluster的key鍵值。從段結構數據字典中,我們不能看到數據表的段信息,只有cluster的段信息。從dba_tables中,我們的確看到數據表成功創建。

 

SQL> select segment_created from dba_tables where wner='TEST' and table_name='EMP';

SEGMENT_CREATED

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

YES

 

此時,我們嘗試往數據表emp添加數據,是被禁止的。

 

SQL> insert into emp select empno, ename, deptno from scott.emp;

insert into emp select empno, ename, deptno from scott.emp

ORA-02032: 聚簇表無法在簇索引建立之前使用

 

在這里,我們意識到使用cluster還需要創建專門的cluster index。為了進行連接測試,先創建第二張數據表。

 

SQL> create table dept (deptno number primary key, deptname varchar2(10)) cluster emp_dept(deptno);

Table created

SQL> select segment_created from dba_tables where wner='TEST' and table_name='DEPT';

SEGMENT_CREATED

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

YES

 

同時,創建了需要的索引結構。

 

SQL> create index idx_emp_dept on cluster emp_dept;

Index created

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name in ('EMP_DEPT','IDX_EMP_DEPT');

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

INDEX                       1           4          538      65536          8

CLUSTER                     1           4          522      65536          8

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name='EMP';

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name='DEPT';

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

--Index元數據信息

SQL> select index_type, table_name, table_type, UNIQUENESS from dba_indexes where wner='TEST' and index_name='IDX_EMP_DEPT';

INDEX_TYPE                TABLE_NAME                     TABLE_TYPE  UNIQUENESS

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

CLUSTER                     EMP_DEPT                       CLUSTER     UNIQUE

 

我們創建了兩張數據表和一個索引,只有cluster和索引成為了段對象。明顯的是兩個數據表都包括保存在了cluster段結構中。

 

創建索引的過程和普通索引是不同的。我們沒有給數據表建索引,而是給cluster對象。從dba_indexes視圖中,可以看到差異和不同。

 

下面我們灌入數據。

 

SQL> insert into dept select deptno, dname from scott.dept;

4 rows inserted

SQL> insert into emp select empno, ename, deptno from scott.emp;

14 rows inserted

SQL> commit;

Commit complete

 

此時,段結構依然維持一個cluster和一個索引的形態。

 

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name='EMP';

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name='DEPT';

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

SQL> select SEGMENT_TYPE, extents, HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS from dba_segments where wner='TEST' and segment_name in ('EMP_DEPT','IDX_EMP_DEPT');

SEGMENT_TYPE          EXTENTS HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS

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

CLUSTER                     1           4          522      65536          8

INDEX                       1           4          538      65536          8

 

使用cluster最大的好處在于連接,我們查看一下連接情況下的執行計劃。

 

SQL> explain plan for select * from emp a, dept b where a.deptno=b.deptno;

Explained

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

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

Plan hash value: 1709228156

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

| Id  | Operation            | Name         | Rows  | Bytes | Cost (%CPU)| Time

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

|   0 | SELECT STATEMENT      |             |    14 |   350 |     6   (0)| 00:0

|   1 |  NESTED LOOPS         |             |    14 |   350 |     6   (0)| 00:0

|   2 |   TABLE ACCESS FULL   | DEPT        |     4 |    48 |     3   (0)| 00:0

|   3 |   TABLE ACCESS CLUSTER| EMP         |     4 |    52 |     1   (0)| 00:0

|*  4 |    INDEX UNIQUE SCAN  | IDX_EMP_DEPT |    1 |       |     0   (0)| 00:0

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

Predicate Information (identified by operation id):

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

   4 - access("A"."DEPTNO"="B"."DEPTNO")

16 rows selected

 

cluster本質上就是一個容器,如果我們需要刪除cluster,需要將其中數據表對象全部刪除之后,方可執行。或者使用including tables子句。

 

SQL> drop cluster emp_dept;

drop cluster emp_dept

ORA-00951: 簇非空

SQL> drop cluster emp_dept including tables;

Cluster dropped

本部分介紹的是B樹聚簇,也是簡單的一種聚簇形式。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

师宗县| 营口市| 尤溪县| 会同县| 麦盖提县| 彝良县| 新安县| 曲靖市| 定南县| 凌海市| 廉江市| 庆元县| 锦屏县| 右玉县| 祁门县| 崇信县| 木里| 梅河口市| 遂平县| 镇沅| 宜兰市| 枣强县| 巢湖市| 丹东市| 抚顺市| 神池县| 齐齐哈尔市| 保康县| 丹寨县| 寿宁县| 乐亭县| 密云县| 绥德县| 禄丰县| 衡阳市| 崇文区| 曲松县| 本溪市| 正阳县| 房产| 竹溪县|