Oracle SQL调优之表设计
在看《收获,不止sql优化》一书,并做了笔记,本博客介绍一下一些和调优相关的表比如分区表、临时表、索引组织表、簇表以及表压缩技术
分区表使用与查询频繁而更新数据不频繁的情况,不过要记得加全局索引,而不加分区索引,分区类型:分区分为范围分区、列表分区、HASH分区、组合分区四种,用了分区表,查询时就定位到对应的区,而不用全表,所以查询效率比普通表好,当然有很多细节,还是建议看《收获,不止sql优化》一书
分区表详细看:https://smilenicky.blog.csdn.net/article/details/90315716
- 范围分区
关键字partition by range
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;
- 散列分区
散列分区也叫hash分区,partitions后接分区数,尽量设置为偶数,
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;
- 组合分区
主要有两种:oracle11之前只支持范围列表分区(RANGE-LIST)和范围散列分区(RANGE-HASH),oracle11之后支持(范围范围分区)RANGE-RANGE、 (列表范围分区)LIST-RANGE、(列表散列分区)LIST-HASH、(列表列表分区)LIST-LIST这几种组合,为了避免每个主分区中都写相同的从分区,可以用模板方式(subpartition template)
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;
普通表和分区表区别,分区表分成几部分就有几个segment
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');
分区相关操作
- Split分区
拆分分区,范围分区和列表分区都适合分区,注意不能对HASH类型的分区进行拆分
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;
- TRUNCATE分区
TRUNCATE是指删除分区的数据,并不会删除分区
ALTER TABLE list_part_tab TRUNCATE PARTITION P2;
TRUNCATE子分区
ALTER TABLE list_part_tab TRUNCATE SUBPARTITION P13SUB1;
- 合并分区
合并分区是将相邻的分区合并成一个分区,结果分区将采用较高分区的界限,值得注意的是,不能将分区合并到界限较低的分区
ALTER TABLE list_part_tab MERGE PARTITIONS P1,P2 INTO PARTITION P2;
- 接合分区(coalesca)
将散列分区中的数据接合到其它分区中,当散列分区中的数据比较大时,可以增加散列分区,然后进行接合,注意接合只适用于散列分区
ALTER TABLE list_part_tab COALESCA PARTITION;
- 重命名分区
ALTER TABLE SAlist_part_tabLES RENAME PARTITION P11 TO P1;
- 交换分区
交换分区是说交换两张表结构一样的表的数据,注意最好加上including indexs更新全局索引,不加的话,全局索引会失效
alter table list_part_tab exchange partition p1 with table range_part_tab including indexs update global indexs;
分区相关查询
*查询数据库所有分区表的信息
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优化》一书作者的归纳
操作动作 | 操作命令 | 是否失效(全局索引) | 如何避免(全局索引) | 是否失效(分区索引) | 如何避免(分区索引) |
---|---|---|---|---|---|
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:表结构设计时,最好存放什么数据就设计为什么类型,避免执行时类型转换,影响性能
Oracle SQL调优之表设计的更多相关文章
- Oracle SQL 调优健康检查脚本
Oracle SQL 调优健康检查脚本 我们关注数据库系统的性能,进行数据库调优的主要工作就是进行SQL的优化.良好的数据架构设计.配合应用系统中间件和写一手漂亮的SQL,是未来系统上线后不出现致命性 ...
- Oracle SQL调优记录
目录 一.前言 二.注意点 三.Oracle执行计划 四.调优记录 @ 一.前言 本博客只记录工作中的一次oracle sql调优记录,因为数据量过多导致的查询缓慢,一方面是因为业务太过繁杂,关联了太 ...
- Oracle SQL调优之分区表
目录 一.分区表简介 二.分区表优势 三.分区表分类 3.1 范围分区 3.2 列表分区 3.3 散列分区 3.4 组合分区 四.分区相关操作 五.分区相关查询 附录:分区表索引失效的操作 一.分区表 ...
- Oracle SQL调优系列之SQL Monitor Report
@ 目录 1.SQL Monitor简介 2.捕捉sql的前提 3.SQL Monitor 参数设置 4.SQL Monitor Report 4.1.SQL_ID获取 4.2.Text文本格式 4. ...
- hbase性能调优_表设计案例
hbase性能调优案例 1.人员-角色 人员有多个角色 角色优先级 角色有多个人员 人员 删除添加角色 角色 可以添加删除人员 人员 角色 删除添加 设计思路 person表 ...
- Oracle SQL 调优之 sqlhc
SQL 执行慢,如何 快速准确的优化. sqlhc 就是其中最好工具之一 通过获得sql所有的执行计划,列出实际的性能的瓶颈点,列出 sql 所在的表上的行数,每一列的数据和分布,现有的索引,sql ...
- Oracle SQL调优之绑定变量用法简介
目录 一.SQL执行过程简介 二.绑定变量典型用法 2.1.在SQL中绑定变量 2.2.在PL/SQL中使用绑定变量 2.3.PL/SQL批量绑定变量 2.4.Java代码里使用绑定变量 最近在看&l ...
- Oracle SQL调优
在多数情况下,Oracle使用索引t来更快地遍历表,优化器主要根据定义的索引来提高性能. 但是,如果在SQL语句的where子句中写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种 ...
- ORACLE SQL调优案例一则
收到监控告警日志文件(Alert)的作业发出的告警邮件,表空间TEMPSCM2不能扩展临时段,说明临时表空间已经被用完了,TEMPSCM2表空间不够用了 Dear All: The Instanc ...
随机推荐
- python同名函数同名参数问题
如果python有两个函数的函数名与参数列表都相同那么调用该函数时,哪个函数在后,则哪个被最终调用. 举例如下: def test(): print "before hello" ...
- IT兄弟连 Java语法教程 数组 什么是数组
数组是编程语言中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值.Java语言的数组则具有其特有的特征, ...
- 基于python的selenium常用操作方法(2)
9 多表单切换 在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位.这 ...
- springboot实践1
环境安装 安装jdk 推荐安装jkd1.8+,我使用的是mac,假设已经安装好homebrew,则jdk的安装指令是: brew install java 在 ~/zshrc ,添加两行 export ...
- PHP框架 fastadmin 根据条件判断字段的显示隐藏
首先,因为fastadmin的JS里面字段不支持function函数 里面只能填false或true,不能动态判断显示隐藏, 后面通过看文档发现能在表格初始化的地方判断 如图,就可以实现根据lin ...
- frigate_TUNNEL
#coding=utf-8 Result=open('result.txt',"w") FileTunnel = open('tunnel.txt').readlines() Ne ...
- Python爬取6271家死亡公司数据,看十年创业公司消亡史
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 朱小五 凹凸玩数据 PS:如有需要Python学习资料的小伙伴可以加 ...
- Java生鲜电商平台-商品分类表和商品类型表的区别与数据库设计
Java生鲜电商平台-商品分类表和商品类型表的区别与数据库设计 二者服务的对象不一样 目的也是不一样的 商品分类是为商品服务的 用来管理商品 商品类型是为扩展属性服务的 用来管理属性 举例:[转] ...
- HTML常用标签四
表单 表单的组成 一个完整的表单通常由表单域.表单控件(也称表单元素)和提示信息3各部分组成 表单域 表单域是一个包含表单元素的区域 在HTML中,<form> 标签用去定义表单域,以实现 ...
- Xcode模拟器无法启动解决办法
今天遇到模拟器无法启动问题,点击模拟器或者Xcode build模拟器就一直跳,跳一会就不跳了,然后查看模拟器状态,显示为无响应.或者黑屏,等半天不动. 如果你有类似情况可以尝试在终端执行以下命令: ...