在看《收穫,不止sql優化》一書,並作了筆記,本博客介紹一下一些和調優相關的表好比分區表、臨時表、索引組織表、簇表以及表壓縮技術sql
分區表使用與查詢頻繁而更新數據不頻繁的狀況,不過要記得加全局索引,而不加分區索引,分區類型:分區分爲範圍分區、列表分區、HASH分區、組合分區四種,用了分區表,查詢時就定位到對應的區,而不用全表,因此查詢效率比普通表好,固然有不少細節,仍是建議看《收穫,不止sql優化》一書數據庫
分區表詳細看:https://smilenicky.blog.csdn.net/article/details/90315716oracle
create table range_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by range (deal_date) ( partition p1 values less than (TO_DATE('2018-11-01','YYYY-MM-DD')), partition p2 values less than (TO_DATE('2018-12-02','YYYY-MM-DD')), partition p3 values less than (TO_DATE('2019-01-01','YYYY-MM-DD')), partition p4 values less than (TO_DATE('2019-02-01','YYYY-MM-DD')), partition p5 values less than (TO_DATE('2019-03-01','YYYY-MM-DD')), partition p6 values less than (TO_DATE('2019-04-01','YYYY-MM-DD')), partition p7 values less than (TO_DATE('2019-05-01','YYYY-MM-DD')), partition p8 values less than (TO_DATE('2019-06-01','YYYY-MM-DD')), partition p9 values less than (TO_DATE('2019-07-01','YYYY-MM-DD')), partition p10 values less than (TO_DATE('2019-08-01','YYYY-MM-DD')) ); insert into range_part_tab (seq, deal_date, unit_code, remark) select rownum, to_date(to_char(sysdate-365, 'J') + trunc(DBMS_RANDOM.value(0, 365)),'J'), ceil(dbms_random.value(210,220)), rpad('*', 1, '*') from dual connect by rownum <= 1000;
create table list_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by list (unit_code) ( partition p1 values (211), partition p2 values (212), partition p3 values (213), partition p4 values (214), partition p5 values (215), partition p6 values (216), partition p7 values (217), partition p8 values (218), partition p9 values (219), partition p10 values (220), partition p0 values (DEFAULT) ); insert into list_part_tab (seq, deal_date, unit_code, remark) select rownum, to_date(to_char(sysdate-365, 'J') + trunc(DBMS_RANDOM.value(0, 365)),'J'), ceil(dbms_random.value(210,220)), rpad('*', 1, '*') from dual connect by rownum <= 1000; commit;
create table hash_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by hash (deal_date) partitions 12; insert into hash_part_tab (seq, deal_date, unit_code, remark) select rownum, to_date(to_char(sysdate-365, 'J') + trunc(DBMS_RANDOM.value(0, 365)),'J'), ceil(dbms_random.value(210,220)), rpad('*', 1, '*') from dual connect by rownum <= 1000; commit;
create table range_list_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by range (deal_date) subpartition by list (unit_code) subpartition template (subpartition s1 values (211), subpartition s2 values (212), subpartition s3 values (213), subpartition s4 values (214), subpartition s5 values (215), subpartition s6 values (216), subpartition s7 values (217), subpartition s8 values (218), subpartition s9 values (219), subpartition s10 values (220), subpartition s0 values (DEFAULT) ) ( partition p1 values less than (TO_DATE('2018-11-01','YYYY-MM-DD')), partition p2 values less than (TO_DATE('2018-12-02','YYYY-MM-DD')), partition p3 values less than (TO_DATE('2019-01-01','YYYY-MM-DD')), partition p4 values less than (TO_DATE('2019-02-01','YYYY-MM-DD')), partition p5 values less than (TO_DATE('2019-03-01','YYYY-MM-DD')), partition p6 values less than (TO_DATE('2019-04-01','YYYY-MM-DD')), partition p7 values less than (TO_DATE('2019-05-01','YYYY-MM-DD')), partition p8 values less than (TO_DATE('2019-06-01','YYYY-MM-DD')), partition p9 values less than (TO_DATE('2019-07-01','YYYY-MM-DD')), partition p10 values less than (TO_DATE('2019-08-01','YYYY-MM-DD')) ); insert into range_list_part_tab (seq, deal_date, unit_code, remark) select rownum, to_date(to_char(sysdate-365, 'J') + trunc(DBMS_RANDOM.value(0, 365)),'J'), ceil(dbms_random.value(210,220)), rpad('*', 1, '*') from dual connect by rownum <= 1000; commit;
普通表和分區表區別,分區表分紅幾部分就有幾個segmentless
select segment_name, partition_name, segment_type, bytes / 1024 / 1024 "字節數(M)", tablespace_name from user_segments where segment_name IN ('RANGE_PART_TAB', 'NOR_TAB');
分區相關操做dom
create table list_part_tab (seq number,deal_date date,unit_code number,remark varchar2(100)) partition by list (unit_code) ( partition p1 values (211), partition p2 values (212), partition p3 values (213), partition p4 values (214), partition p5 values (215), partition p6 values (216), partition p7 values (217), partition p8 values (218), partition p9 values (219), partition p10 values (220), partition p0 values (DEFAULT) ); alter table list_part_tab split partition p10 at(220) into (PARTITION p11,PARTITION p12);
ALTER TABLE list_part_tab ADD PARTITION P13 VALUES LESS THAN(250);
新增子分區性能
ALTER TABLE list_part_tab MODIFY PARTITION P13 ADD SUBPARTITION P13SUB1 VALUES(350);
ALTER TABLE list_part_tab DROP PARTITION P13;
刪除子分區優化
ALTER TABLE list_part_tab DROP SUBPARTITION P13SUB1;
ALTER TABLE list_part_tab TRUNCATE PARTITION P2;
TRUNCATE子分區ui
ALTER TABLE list_part_tab TRUNCATE SUBPARTITION P13SUB1;
ALTER TABLE list_part_tab MERGE PARTITIONS P1,P2 INTO PARTITION P2;
ALTER TABLE list_part_tab COALESCA PARTITION;
ALTER TABLE SAlist_part_tabLES RENAME PARTITION P11 TO P1;
alter table list_part_tab exchange partition p1 with table range_part_tab including indexs update global indexs;
分區相關查詢
*查詢數據庫全部分區表的信息spa
select * from DBA_PART_TABLES
select pt.partitioning_type, pt.subpartitioning_type, pt.partition_count from user_part_tables pt
SELECT tab.* FROM USER_TAB_PARTITIONS tab WHERE TABLE_NAME='LIST_PART_TAB'
select column_name, object_type, column_position from user_part_key_columns where name = 'LIST_PART_TAB';
select sum(bytes / 1024 / 1024) from user_segments where segment_name = 'LIST_PART_TAB';
select partition_name, segment_type, bytes from user_segments where segment_name = 'LIST_PART_TAB';
select segment_name, segment_type, sum(bytes) / 1024 / 1024 from user_segments where segment_name in (select index_name from user_indexes where table_name = 'LIST_PART_TAB') group by segment_name, segment_type;
select table_name, partition_name, last_analyzed, partition_position, num_rows from user_tab_statistics where table_name = 'LIST_PART_TAB';
select table_name, index_name, last_analyzed, blevel, num_rows, leaf_blocks, distinct_keys, status from user_indexes where table_name = 'LIST_PART_TAB';
select index_name, column_name, column_position from user_ind_columns where table_name = 'LIST_PART_TAB';
select ind.index_name, ind.table_name, ind.blevel, ind.num_rows, ind.leaf_blocks, ind.distinct_keys from user_indexes ind where status = 'INVALID';
select a.blevel, a.leaf_blocks, a.index_name, b.table_name, a.partition_name, a.status from user_ind_partitions a, user_indexes b where a.index_name = b.index_name and a.status = 'UNUSABLE';
分區表索引失效的操做,表格來自《收穫,不止SQL優化》一書做者的概括.net
操做動做 | 操做命令 | 是否失效(全局索引) | 如何避免(全局索引) | 是否失效(分區索引) | 如何避免(分區索引) |
---|---|---|---|---|---|
truncate分區 | alter table part_tab_trunc truncate partition p1 ; | 失效 | alter table part_tab_trunc truncate partition p1 Update GLOBAL indexes; | 沒影響 | N/A |
drop分區 | alter table part_tab_drop drop partition p1; | 失效 | alter table part_tab_drop drop partition p1 Update GLOBAL indexes; | 沒影響 | N/A |
split分區 | alter table part_tab_split SPLIT PARTITION P_MAX at(30000) into (PARTITION p3,PARTITION P_MAX); | 失效 | alter table part_tab_split SPLIT PARTITION P_MAX at (30000) into (PARTITION p3,PARTITION P_MAX) update global indexes; | 沒影響 | N/A |
add分區 | alter table part_tab_add add PARTITION p6 values less than (60000); | 沒影響 | N/A | 沒影響 | N/A |
exchange分區 | alter table part_tab_exch exchange partition p1 with table normal_tab including indexes; | 失效 | alter table part_tab_exch exchange partition p1 with table normal_tab including indexes update global indexes; | 沒影響 | N/A |
全局臨時表:全局臨時表分爲兩種類型,一種是基於會話的全局臨時表(on commit preserve rows);一種是基於事務的全局臨時表(on commit delete rows)
create global temporary table [臨時表名] on commit (preserve rows)|(delete rows) as select * from [數據表];
eg:
create global temporary table tmp on commit preserve rows as select * from dba_objects;
全局臨時表特色:
select * from v$mystat where rownum=1;
ps:基於事務的臨時表在事務提交和會話鏈接退出時,臨時表數據會被刪除;基於會話的臨時表就是在會話鏈接退出時,臨時表數據被刪除
索引組織表:
壓縮技術
ALTER TABLE t MOVE COMPRESS ;
create index idx2_object_union on t2 (owner , object_type , object_name ); ALTER index idx2_object_union rebuild COMPRESS ;
簇表:簇由一組共享多個數據塊的多個表組成,它將這些表的相關行一塊兒存儲到相同數據塊中,這樣能夠減小查詢數據所需的磁盤讀取量。新建簇以後,在簇中新建的表被稱爲簇表
ps:表結構設計時,最好存放什麼數據就設計爲何類型,避免執行時類型轉換,影響性能