ITPub博客

首页 > 数据库 > Oracle > [20181026]12c Attribute Clustering特性.txt

[20181026]12c Attribute Clustering特性.txt

Oracle 作者:lfree 时间:2018-10-26 22:10:11 0 删除 编辑

[20181026]12c Attribute Clustering特性.txt

--//作者很早的演示,链接:
--//我当时的测试环境12.1.0.1,还不支持这个特性,一直没有机会测试:
--//我当时想到底有多少人会使用这个特性整理组织表数据.

--//首先简单介绍:
Attribute Clustering实际上按照特定的字段组织表,使相同的值聚集起来,总的来讲就是减少索引的聚集因子.

One of the really cool new features introduced in 12.1.0.2 is Attribute Clustering. This new table based attribute
allows you to very easily cluster data in close physical proximity based on the content of specific columns.

--//直接拿作者的例子测试.

1.环境:
SCOTT@test01p> @ ver1
PORT_STRING                    VERSION        BANNER                                                                               CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0           12.2.0.1.0     Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production              0

2.测试:
SCOTT@test01p> create table ziggy (id number, code number, name varchar2(30));
Table created.

SCOTT@test01p> insert into ziggy select rownum, mod(rownum,100), 'DAVID BOWIE' from dual connect by level <= 200000;
200000 rows created.
--//我减少记录数200000.
SCOTT@test01p> commit;
Commit complete.

SCOTT@test01p> exec dbms_stats.gather_table_stats(ownname=>user, tabname=>'ZIGGY', estimate_percent=>null, method_opt=>'FOR ALL COLUMNS SIZE 1');
PL/SQL procedure successfully completed.

SCOTT@test01p> create index ziggy_code_i on ziggy(code);
Index created.

SCOTT@test01p> select index_name, clustering_factor, num_rows from user_indexes where index_name='ZIGGY_CODE_I';
INDEX_NAME           CLUSTERING_FACTOR   NUM_ROWS
-------------------- ----------------- ----------
ZIGGY_CODE_I                     68878     200000

--//说明这样建立的索引(字段code)的clustering_factor会很高.

3.执行sql语句看看:
SCOTT@test01p> alter session set statistics_level=all;
Session altered.

SCOTT@test01p> set FEEDBACK only
SCOTT@test01p> select * from ziggy where code = 42;
        ID       CODE NAME
---------- ---------- --------------------

2000 rows selected.

SCOTT@test01p> set FEEDBACK 6
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  9svg0v4s134jh, child number 0
-------------------------------------
select * from ziggy where code = 42
Plan hash value: 2421001569
---------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name  | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |       |      1 |        |       |   206 (100)|          |   2000 |00:00:00.01 |     735 |
|*  1 |  TABLE ACCESS FULL| ZIGGY |      1 |   2000 | 40000 |   206   (1)| 00:00:01 |   2000 |00:00:00.01 |     735 |
---------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / ZIGGY@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("CODE"=42)

--//可以发现群集因子太高了,oracle选择全表扫描。

SCOTT@test01p> set FEEDBACK only
SCOTT@test01p> select /*+ index (ziggy, ziggy_code_i) */ * from ziggy where code = 42;
        ID       CODE NAME
---------- ---------- --------------------

2000 rows selected.

SCOTT@test01p> set FEEDBACK 6

SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  568j8hhfby3r4, child number 0
-------------------------------------
select /*+ index (ziggy, ziggy_code_i) */ * from ziggy where code = 42
Plan hash value: 3294205578
-------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name         | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |
-------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |              |      1 |        |       |   693 (100)|          |   2000 |00:00:00.16 |     712 |      8 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| ZIGGY        |      1 |   2000 | 40000 |   693   (0)| 00:00:01 |   2000 |00:00:00.16 |     712 |      8 |
|*  2 |   INDEX RANGE SCAN                  | ZIGGY_CODE_I |      1 |   2000 |       |     4   (0)| 00:00:01 |   2000 |00:00:00.16 |      16 |      8 |
-------------------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / ZIGGY@SEL$1
   2 - SEL$1 / ZIGGY@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("CODE"=42)

--//我建立的数据集合偏小,buffers差别不大。但是cost=693比全表扫描206多。

4.建立新表具有Attribute Clustering.

SCOTT@test01p> create table ziggy2 (id number, code number, name varchar2(30)) clustering by linear order (code) without materialized zonemap;
Table created.

--//链接的说明:
The CLUSTERING BY LINEAR ORDER clause orders data in the table based on the specified columns, in this case the CODE
column. Up to 10 columns can be included using this particular technique (there are other attribute clustering options
which I'll again cover in later articles, yes I'll be writing quite a few new articles) :) WITHOUT MATERIALIZED ZONEMAP
means I don't want to create these new Zone Maps index structures at this stage which could potentially reduce the
amount of table storage needed to be accessed (again, I'll discuss these at another time).

--//实际上CLUSTERING BY LINEAR ORDER就是建立表按照code组织.字段最多包括10个.
--//按照作着介绍必须采用直接路径插入导入数据才有attribute clustering或者选择重新组织表.

SCOTT@test01p> insert /*+ append */ into ziggy2 select * from ziggy;
200000 rows created.

SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  0arqdyc9vznpg, child number 0
-------------------------------------
insert /*+ append */ into ziggy2 select * from ziggy
Plan hash value: 1975011999
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name   | Starts | E-Rows |E-Bytes|E-Temp | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  | Writes |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                 |        |      1 |        |       |       |  1425 (100)|          |      0 |00:00:00.62 |    3691 |     16 |    691 |       |       |          |
|   1 |  LOAD AS SELECT                  | ZIGGY2 |      1 |        |       |       |            |          |      0 |00:00:00.62 |    3691 |     16 |    691 |  2068K|  2068K| 2068K (0)|
|   2 |   OPTIMIZER STATISTICS GATHERING |        |      1 |    200K|  3906K|       |  1425   (1)| 00:00:01 |    200K|00:00:00.49 |    2395 |     16 |      0 |   256K|   256K|          |
|   3 |    SORT ORDER BY                 |        |      1 |    200K|  3906K|  6288K|  1425   (1)| 00:00:01 |    200K|00:00:00.08 |     725 |      0 |      0 |  8912K|  1165K| 7921K (0)|
|   4 |     TABLE ACCESS FULL            | ZIGGY  |      1 |    200K|  3906K|       |   206   (1)| 00:00:01 |    200K|00:00:00.01 |     725 |      0 |      0 |       |       |          |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   4 - SEL$1 / ZIGGY@SEL$1
--//注意看id=3的执行计划SORT ORDER BY,隐含排序code字段导入表.
SCOTT@test01p> commit;
Commit complete.

SCOTT@test01p> create index ziggy2_code_i on ziggy2(code);
Index created.

SCOTT@test01p> exec dbms_stats.gather_table_stats(ownname=>user, tabname=>'ZIGGY2',estimate_percent=>null, method_opt=>'FOR ALL COLUMNS SIZE 1');
PL/SQL procedure successfully completed.

SCOTT@test01p> select index_name, clustering_factor, num_rows from user_indexes where index_name='ZIGGY2_CODE_I';
INDEX_NAME           CLUSTERING_FACTOR   NUM_ROWS
-------------------- ----------------- ----------
ZIGGY2_CODE_I                      691     200000

--//前面CLUSTERING_FACTOR=68878,而现在表ZIGGY2才691。

SCOTT@test01p> set FEEDBACK only
SCOTT@test01p> select * from ziggy2 where code=42;
        ID       CODE NAME
---------- ---------- --------------------

2000 rows selected.

SCOTT@test01p> set FEEDBACK 6
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  0vjk3yq2ks48x, child number 0
-------------------------------------
select * from ziggy2 where code=42
Plan hash value: 16801974
-----------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name          | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |               |      1 |        |       |    11 (100)|          |   2000 |00:00:00.01 |      34 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| ZIGGY2        |      1 |   2000 | 40000 |    11   (0)| 00:00:01 |   2000 |00:00:00.01 |      34 |
|*  2 |   INDEX RANGE SCAN                  | ZIGGY2_CODE_I |      1 |   2000 |       |     4   (0)| 00:00:01 |   2000 |00:00:00.01 |      16 |
-----------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / ZIGGY2@SEL$1
   2 - SEL$1 / ZIGGY2@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("CODE"=42)

--//oracle执行计划选择索引范围扫描。

5.对于ziggy表可以修改属性,重新组织表:

SCOTT@test01p> alter table ziggy add clustering by linear order(code) without materialized zonemap;
Table altered.

SCOTT@test01p> alter table ziggy move;
Table altered.

SCOTT@test01p> alter index ziggy_code_i rebuild;
Index altered.

SCOTT@test01p> select index_name, clustering_factor, num_rows from user_indexes where index_name='ZIGGY_CODE_I';
INDEX_NAME           CLUSTERING_FACTOR   NUM_ROWS
-------------------- ----------------- ----------
ZIGGY_CODE_I                       691     200000

--//这样执行select * from ziggy where code=42;必然选择索引,不贴出执行计划了。

6.总结:
--//我觉得应该很少有人使用这个特性,总觉得这样仅仅减少手工操作的麻烦.比如你想手工按照code导入.也许操作需要许多步骤.

--//补充测试:
SCOTT@test01p> select table_name,clustering from dba_tables where owner=user and table_name in ('ZIGGY','ZIGGY2','DEPT');
TABLE_NAME           CLU
-------------------- ---
DEPT                 NO
ZIGGY2               YES
ZIGGY                YES

SCOTT@test01p> @ddl scott.ZIGGY
C100
------------------------------------------------------------------------
  CREATE TABLE "SCOTT"."ZIGGY"
   (    "ID" NUMBER,
        "CODE" NUMBER,
        "NAME" VARCHAR2(30)
   ) SEGMENT CREATION IMMEDIATE
  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 FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"
 CLUSTERING
 BY LINEAR ORDER ("SCOTT"."ZIGGY"."CODE")
   YES ON LOAD  YES ON DATA MOVEMENT
 WITHOUT MATERIALIZED ZONEMAP ;

--//不知道那个表记录 CLUSTERING BY LINEAR ORDER ("SCOTT"."ZIGGY"."CODE")信息。先暂时放一下。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/267265/viewspace-2217739/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    2852
  • 访问量
    6639742