Oracle Database 安装Oracle 19c Linux下安装 rpm方式 从Oracle官网下载安装包 Linux x86-64 RPM
https://www.oracle.com/database/technologies/oracle-database-software-downloads.html
安装帮助文档
https://docs.oracle.com/en/database/oracle/oracle-database/19/ladbi/preface.html#GUID-071A6B76-11E3-4421-963E-41DA6F2EF07A
下载 preinstall
下载地址
https://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/index.html,浏览器搜索-19c
或者
curl -o oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm https://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackage/oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm
安装,首先执行
yum localinstall -y oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm
会提示缺少依赖
可以去RPM源网站下载
http://www.rpmfind.net/linux/rpm2html/search.php?query=compat-libcap1(x86-64)
安装
rpm -ivh compat-libcap1-1.10-7.el7.x86_64.rpm
再次执行
yum localinstall -y oracle-database-preinstall-19c-1.0-3.el7.x86_64.rpm
安装数据库
yum localinstall -y oracle-database-ee-19c-1.0-1.x86_64.rpm
配置数据库
/etc/init.d/oracledb_ORCLCDB-19c configure
过程较长,等待即可
可能会JDK报错
配置完成后设置当前用户下的环境变量
vim /etc/profile.d/oracle19c.sh export ORACLE_HOME=/opt/oracle/product/19c/dbhome_1 export PATH=$PATH:/opt/oracle/product/19c/dbhome_1/bin export ORACLE_SID=ORCLCDB# 保存退出,执行 source /etc/profile.d
验证安装是否正确
passwd oracle su oracle sqlplus / as sysdba# 提示 SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 17 12:25:27 2022 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle. All rights reserved. Connected to an idle instance.
启动监听
Docker方式 安装Docker
sudo wget -qO- https://get.docker.com/ | bash docker --version systemctl start docker systemctl status docker systemctl enable docker
拉取镜像 quay.io/maksymbilenko/oracle-12c
docker pull quay.io/maksymbilenko/oracle-12c
如果有本地镜像则使用
docker build -t quay.io/maksymbilenko/oracle-12c .
构建容器
# 首先创建本地目录 mkdir /oracle/data# 授予权限 chmod -R 777 /oracle/data docker run --name o12c -d -p 8080:8080 -p 1521:1521 -v /oracle/data:/u01/app/oracle quay.io/maksymbilenko/oracle-12c# 查看日志 docker logs -f # 字符串ID
安装完成
数据库连接信息
hostname: localhost port: 1521 sid: xe service name: xe username: system password: oracle
进入容器修改账号密码设置
# 查看所有容器信息 docker ps -a docker exec -it [containerID] /bin/bash# 切换成oracle用户 su oracle# 进入sqlplus $ ORACLE_HOME/bin/sqlplus / as sysdba SQL*Plus: Release 12.1.0.2.0 Production on Sun Aug 1 03:15:37 2021 Copyright (c) 1982, 2014, Oracle. All rights reserved. Connected to: Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production# 设置密码有效期为无限制 SQL> ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED; Profile altered.SQL> alter user SYSTEM account unlock; User altered.# 创建一个账号为act_test的用户密码设置为test SQL> create user act_test identified by test ; User created.# 为这个用户赋予管理员的权限 SQL> grant dba to act_test; Grant succeeded.# ctrl + p + q 退出容器(注意不要exit 退出,防止容器直接关闭了)
Windows下安装 Oracle SQL Developer 设置自动提示 工具栏 -> 工具 -> 首选项 -> 代码编辑器 -> 完成设置
设置代码模板 工具栏 -> 工具 -> 首选项 -> 代码编辑器 -> 代码模板
同时打开多个表 工具栏 -> 工具 -> 首选项 -> 数据库 ->对象查看器
SQL PLUS 解决乱码 sqlplus / as sysdba col parameter for a30 col value for a25 select * from nls_database_parameters; PARAMETER VALUE ------------------------------ ------------------------- NLS_RDBMS_VERSION 19.0.0.0.0 NLS_NCHAR_CONV_EXCP FALSE NLS_LENGTH_SEMANTICS BYTE NLS_COMP BINARY NLS_DUAL_CURRENCY $ NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM NLS_TIME_FORMAT HH.MI.SSXFF AM PARAMETER VALUE ------------------------------ ------------------------- NLS_SORT BINARY NLS_DATE_LANGUAGE AMERICAN NLS_DATE_FORMAT DD-MON-RR NLS_CALENDAR GREGORIAN NLS_NUMERIC_CHARACTERS ., NLS_NCHAR_CHARACTERSET AL16UTF16 NLS_CHARACTERSET AL32UTF8 NLS_ISO_CURRENCY AMERICA NLS_CURRENCY $ NLS_TERRITORY AMERICA NLS_LANGUAGE AMERICAN
NLS_LANG
的组成规则为 NLS_LANGUAGE_NLS_TERRITORY.NLS_CHARACTERSET
vim ~/.bash_profile export NLS_LANG="AMERICAN_AMERICA.AL32UTF8"
解决控制台输错命令删除 使用Ctrl + backspace
代替backspace
登录 # 以oracle账号登录 su oracle$ ORACLE_HOME/bin/sqlplus / as sysdba
修改sys密码 sqlplus /nolog conn as sysdba alter user sys identified by 123456;
CDB 和 PDB
命令:如何查看当前的位置是CDB还是PDB使用sys登录,输入命令:
create pluggable database pdb1 admin user pdb1 identified by 1 file_name_convert=('/opt/oracle/oradata/ORCLCDB/pdbseed','/opt/oracle/oradata/ORCLCDB/pdb1'); -- 创建PDB,其中pdb1是我创建的可插接式数据库,pdb1是创建的用户,1是密码。file_name_convert是对应目录 show con_name; -- 查看当前所在容器位置 show pdbs; -- 查看所有的PDB alter pluggable database pdb1 open; -- 打开 pdb1 pdb alter pluggable database pdb1 close immediate; -- 立刻关闭 pdb1 alter pluggable database all open; -- 打开 所有 pdb alter session set container=cdb$root; -- pdb切换到cdb alter session set container=pdb1; -- cdb切换到pdb1 -- 查看 cdb、pdb 信息 select name , cdb from v$database; select name,con_id from v$services; select name,con_id,open_mode from v$pdbs;
由于安装Oracle的时候设定PDB数据库为schooldb,故查询到两个PDB数据库
表空间 概述
表空间
表空间是一个逻辑的概念,真正存放数据的是数据文件(data files)
1 个数据库 = N 个表空间(N >= 1) 1 个表空间 = N 个数据文件(dbf)(N >= 1) – 1个数据文件(dbf) 只能属于 1 个表空间
建立表空间的作用
控制数据库占用 ‘磁盘空间’ 的大小
不同类型的数据存储到不同的位置,有利于提高 ‘I/O’ 性能,同时有利于备份和恢复等操作
相关视图 select * from dba_data_files;select * from dba_temp_files;select * from dba_tablespaces;select * from dba_free_space;select distinct t.privilege from dba_sys_privs t where t.privilege like '%TABLESPACE%' ; select t.tablespace_name, t.file_name, t.autoextensible, t.bytes / 1024 / 1024 "SIZE(M)", t.increment_by * 8 / 1024 "NEXT(M)", t.maxbytes / 1024 / 1024 "MAXSIZE(M)" from dba_data_files t;
语法 create [temporary | undo] tablespace "TBS" datafile 'D:\Oracle\TBS.dbf' size 10 m [autoextend off] | [autoextend on next n maxsize m] [logging | nologging] [segment space management auto] [extent management local [uniform size n]]
创建一个永久表空间 “TBS01”,其大小为 10MB
create table space "TBS01" datafile 'D:\Oracle\TBS01.dbf' size 10 m;
创建一个自增表空间 “TBS02”,其大小为 10MB,每次扩展 1MB,最大扩展到 20MB
create table space "TBS02" datafile 'D:\Oracle\TBS02.dbf' size 10 m autoextend on next 1 m maxsize 20 m;
每个用户都有一个默认临时表空间,在创建用户时如果没指定将使用oracle 数据库设置的默认临时表空间,查询方法是:
select property_name,property_value from database_properties where property_value= ‘TEMP’
新建 CREATE TABLE SPACE ACTERP_BD_DEV LOGGING DATAFILE '/u01/app/oracle/oradata/orcl/acterp_bd_dev.dbf' SIZE 2048 m AUTOEXTEND ON NEXT 50 m MAXSIZE 20480 m EXTENT MANAGEMENT LOCAL ;CREATE TEMPORARY TABLESPACE ACTERP_BD_DEV_TEMP TEMPFILE '/u01/app/oracle/oradata/orcl/acterp_bd_dev_temp.dbf' SIZE 2048 m AUTOEXTEND ON NEXT 50 m MAXSIZE 20480 m EXTENT MANAGEMENT LOCAL ;
查询 select tablespace_name,file_id,bytes/ 1024 / 1024 ,file_name from dba_data_files order by file_id;
修改 alter database datafile 'D:\Oracle\TBS01.dbf' resize 20 m;alter database datafile 'D:\Oracle\TBS01.dbf' autoextend on next 20 m maxsize 1 g;alter table space "TBS01"add datafile 'D:\Oracle\TBS01_1.dbf' size 200 m;
删除 drop user acterp_pre cascade;drop tablespace acterp_pre including contents and datafiles cascade constraint ;drop tablespace acterp_pre_temp including contents and datafiles cascade constraint ;
用户 操作 cdb 新建 CREATE TABLE SPACE ACT_DEV DATAFILE '/opt/oracle/oradata/ORCLCDB/act_dev.dbf' SIZE 100 M AUTOEXTEND ON NEXT 100 M MAXSIZE UNLIMITED LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;create user C##act_dev identified by 123456 default tablespace ACT_DEV;grant dba,connect to C##act_dev;commit ;
删除 drop user pdb1 cascade; #cascade 删除pdb1这个用户的同时,级联删除 pdb1 用户下的所有数据对象,如table 等
修改用户密码
alter user pdb1 identified by 1 ;
pdb # 首先切换到pdbalter session set container= ORCLPDB1; # 创建用户名为 pdb1 密码为 1 的用户create user pdb1 identified by 1 ;grant create session to pdb1;grant create table to pdb1;grant create table space to pdb1;grant create view to pdb1;grant connect ,resource to pdb1;grant dba to pdb1;
non-cdb select tablespace_name,file_id,bytes/ 1024 / 1024 || 'm' as file_size,file_name from dba_data_files order by file_id;CREATE TABLE SPACE ACTERP_PRE LOGGING DATAFILE 'D:\APP\ORACLE\ORADATA\ORCL\acterp_pre.dbf' SIZE 2048 m AUTOEXTEND ON NEXT 50 m MAXSIZE 20480 m EXTENT MANAGEMENT LOCAL ; CREATE TEMPORARY TABLESPACE ACTERP_PRE_TEMP TEMPFILE 'D:\APP\ORACLE\ORADATA\ORCL\acterp_pre_temp.dbf' SIZE 2048 m AUTOEXTEND ON NEXT 50 m MAXSIZE 20480 m EXTENT MANAGEMENT LOCAL ; create user acterp_pre identified by 1 default tablespace ACTERP_PRE temporary tablespace ACTERP_PRE_TEMP;grant create session to acterp_pre;grant create table to acterp_pre;grant create table space to acterp_pre;grant create view to acterp_pre;grant connect ,resource to acterp_pre;grant dba to acterp_pre;commit ;
语法 新建表空间 CREATE TABLE SPACE ACT_DEV DATAFILE '\oracle\data\oradata\xe\FILE_SPECIFICATION1.dbf' SIZE 52428800 AUTOEXTEND ON NEXT 52428800 MAXSIZE 2147483648 EXTENT MANAGEMENT LOCAL ;
解除占用 select l.session_id,o.owner,o.object_namefrom v$locked_object l,dba_objects owhere l.object_id= o.object_id;SELECT sid, serial#, username, osuser FROM v$session where sid = sid;alter system kill session 'sid,serial#' ;
修改表 ALTER TABLE BOOK RENAME TO BIND_PHONE_NUMBER;ALTER TABLE BIND_PHONE_NUMBER ADD (USERNAME VARCHAR2(20 ) );ALTER TABLE BIND_PHONE_NUMBER RENAME COLUMN NAME TO APPNAME;
使用关键字做完表名,列名 使用双引号””形式,如”INDEX”
删除表数据 TRUNCATE TABLE 表名DELETE FROM 表名
从其他表中复制数据到插入一张表中 INSERT INTO table2SELECT * FROM table1;INSERT INTO table1(ID,NAME,TEXT) SELECT SYS_GUID(), t2.NAME, t3.TEXT FROM DUAL, TABLE2 t2, TABLE3 t3;
directory目录 select * from dba_directories;create or replace directory dum_date_dir as '/home/oracle/datatmp' ant read,write on directory dumpdir to username;drop directory DIRENAME;
数据泵 10g开始引入了数据泵(Data Dump)技术,可以快速将数据库元数据和数据快速移动到另一个oracle数据库中
导入 impdp impdp acterp_bd_dev/1@ORCLCDB REMAP_SCHEMA = acterp_bd_dev:acterp_bd_dev table_exists_action = replace directory=data_pump_dir dumpfile=acterp_bd_dev.dmp logfile=impdp_acterp_bd_dev.log
如果是non-cdb
需去掉@SID
内连接与外连接 内连接 合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行
语法:
SELECT 字段列表FROM A表 INNER JOIN B表ON 关联条件WHERE 条件;
类似于:
方式一SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_idFROM employees e JOIN departments dON (e.department_id = d.department_id); 方式二:SELECT employee_id,department_nameFROM employees e,departments dWHERE e.`department_id` = d.department_id;
这种查询方式,它会把所有的符合where条件的字段查询出来。但是有这样一种情况,就是两张表的数据有的不存在某种关系。
缺点:如果我们想要把不满足条件的数据也查询出来,内连接就做不到。
于是引入外连接。
外连接 查询多表时一般要求中出现:查询所有的数据时,就一定会用到外连接。
两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右)外连接。没有匹配的行时,结果表中相应的列为空(NULL)。
满外连接 FULL JOIN
LEFT JOIN UNION RIGHT JOIN
左外连接 语法:
SELECT 字段列表FROM A表 LEFT JOIN B表ON 关联条件WHERE 条件;
类似于:
SELECT e.last_name, e.department_id, d.department_nameFROM employees eLEFT OUTER JOIN departments dON (e.department_id = d.department_id) ;
employees
表中的数据会全部显示出来
右外连接 语法:
SELECT 字段列表FROM A表 RIGHT JOIN B表ON 关联条件WHERE 条件;
类似于:
SELECT e.last_name, e.department_id, d.department_nameFROM employees eRIGHT OUTER JOIN departments dON (e.department_id = d.department_id) ;
departments
表中的数据会全部显示出来
UNION的使用 ·语法:
SELECT column ,... FROM table1UNION [ALL ]SELECT column ,... FROM table2
UNION 操作符返回两个查询的结果集的并集,去除重复记录。
UNION ALL操作符返回两个查询的结果集的并集。对于两个结果集的重复部分,不去重。
Oracle 函数 NVL()
SELECT a.OSPREQID,a.OSPREQNO FROM T_OSP_REQ a,T_OSP_REQDETAIL b WHERE a.OSPREQID = b.OSPREQID AND b.OSPNO IN (SELECT OSPNP FROM T_BPM_OSP WHERE OSPNO IN ('OSP202302280002' )) AND NVL(DATASTATUS, ' ' )<> '撤销'
如果DATASTATUS 为NULL ,则返回**’ ‘,否则返回 DATASTATUS**
官方解释
The Oracle NVL () function allows you to replace null with a more meaningful alternative in the results of a query. The following shows the syntax of the NVL () function: The NVL () function accepts two arguments. If e1 evaluates to null, then NVL () function returns e2. If e1 evaluates to non-null, the NVL () function returns e1.
Oracle NVL()函数允许您在查询结果中用更有意义的替代项替换NULL。下面显示了NVL()函数的语法:NVL()函数接受两个参数。如果e1的计算结果为空,则NVL()函数返回e2。如果e1的计算结果为非空,则nvl()函数返回e1。
DECODE() 用法 DECODE(表达式, 条件1,返回值1,条件2,返回值2)
SELECT DECODE(AMOUNT, 0 , NULL , AMOUNT) FROM T_PO_ORDERDETAIL;
如果AMOUNT 等于0 ,则返回NULL ,否则返回AMOUNT
SELECT DECODE(AMOUNT, 0 , NULL , 1 , 1 , AMOUNT) FROM T_PO_ORDERDETAIL;
如果AMOUNT 等于0 ,则返回NULL ,否则如果AMOUNT等于1,则返回1,否则返回AMOUNT
DECODE替换NVL 在Oracle中,DECODE函数通常可以替换使用NVL函数。DECODE函数可以在字段值满足多个条件时返回不同的结果值,语法如下:
DECODE(expr, search, result, default)
其中,expr是要进行条件判断的表达式,search是需要匹配的条件值,result是匹配成功后返回的结果值,default是在没有匹配成功时返回的默认值。
使用DECODE函数来替换NVL函数的示例如下:
使用NVL函数处理NULL值:
SELECT NVL(name, '未知') AS name FROM user;
使用DECODE函数替换NVL函数:
SELECT DECODE(name, NULL, '未知', name) AS name FROM user;
以上语句中,使用DECODE函数将name参数的NULL值替换为“未知”字符串。当name不为NULL时,返回它本身的值。
LTRIM ltrim(char[,set])
去掉字符串 char 左侧包含在 set 中的任何字符,直到第一个不在 set 中出现的字符为止
RTRIM rtrim(char[,set])
去掉字符串 char 右侧包含在 set 中的任何字符,直到第一个不在 set 中出现的字符为止
SELECT ltrim('abcd' ,'a' ) lefttrim, rtrim('abcde' ,'e' ) righttrim FROM dual; LEFTTRIM RIGHTTRIM bcd abcd
特性 Row Movement ROW MOVEMENT特性最初是在8i时引入的,其目的是提高分区表的灵活性——允许更新Partition Key。这一特性默认是关闭,只是在使用到一些特殊功能时会要求打开。除了之前提到的更新Partition Key,还有2个要求打开的ROW MOVEMENT的功能就是flushback table和Shrink Segment。
先看Flashback Table。这一功能能帮助我们及时回滚一些误操作,防止数据意外丢失。在使用该功能之前,必须先打开ROW MOVEMENT,否则就会抛ORA-08189错误。我们看以下例子,可以说明在使用Flashback Table功能时,ROW MOVEMENT产生了什么作用:
当开启ROW MOVEMENT后,表被顺利的flashback了,数据被找回。此时,再比较flashback前后记录的ROWID,大多数记录的物理位置都变化。这个过程的内部操作, 可以通过对Flashback Table做SQL Trace来进一步观察。
通过Trace,我们不难发现,Flashback Table实际是通过Flashback Query将表中数据进行了一次删除、插入操作,因此ROWID会发生变化。
在更新记录中的Partition Key时,可能会导致该记录超出当前所在分区的范围,需要将其转移到其他对应分区上,因此要求开启ROW MOVEMENT。
这一操作产生影响的特殊之处在于这是个DML操作,是和online transaction密切相关。对于这样一个UPDATE,实际上分为3步:先从原有分区将数据删除;将原数据转移到新分区上;更新数据。
其影响就在于以下几个方面:
分区表 范围分区 create table space tetstbs1 datafile '/opt/oracle/oradata/ORCLCDB/tetstbs1.dbf' size 1 m autoextend on next 5 m maxsize unlimited;create table space tetstbs2 datafile '/opt/oracle/oradata/ORCLCDB/tetstbs2.dbf' size 1 m autoextend on next 5 m maxsize unlimited;create table space tetstbs3 datafile '/opt/oracle/oradata/ORCLCDB/tetstbs3.dbf' size 1 m autoextend on next 5 m maxsize unlimited;create table pt_range_test1( pid number(10 ), pname varchar2(30 ) ) partition by range (pid)( partition p1 values less than(1000 ) tablespace tetstbs1, partition p2 values less than(2000 ) tablespace tetstbs2, partition p3 values less than(maxvalue) tablespace tetstbs3 ) enable row movement;insert into pt_range_test1 (pid, pname) values (1 , '瑶瑶' );insert into pt_range_test1 (pid, pname) values (1500 , '倩倩' );insert into pt_range_test1 (pid, pname) values (null , '优优' );commit ;select * from user_tab_partitions t;select 'P1' 分区名, t.* from pt_range_test1 partition (p1) t union all select 'P2' 分区名, t.* from pt_range_test1 partition (p2) t union all select 'P3' 分区名, t.* from pt_range_test1 partition (p3) t;select 'P1' 分区名, t.* from pt_range_test1 PARTITION (p1) t;select t.* from pt_range_test1 PARTITION (p1) t;select t.* FROM pt_range_test1 t;
列表分区 create table pt_list_test( pid number(10 ), pname varchar2(30 ), sex varchar2(10 ) ) partition by list(sex)( partition p1 values ('MAN' , '男' ) tablespace tetstbs1, partition p2 values ('WOMAN' , '女' ) tablespace tetstbs2, partition p3 values (default ) tablespace tetstbs3 ) enable row movement;insert into pt_list_test (pid, pname, sex) values (1 , '瑶瑶' , '男' );insert into pt_list_test (pid, pname, sex) values (2 , '倩倩' , 'WOMAN' );insert into pt_list_test (pid, pname, sex) values (3 , '优优' , 'GOD' );insert into pt_list_test (pid, pname, sex) VALUES (4 , '雨雨' , '女' );insert into pt_list_test (pid, pname, sex) VALUES (5 , '闫闫' , 'MAN' );commit ;update pt_list_test set sex = '男' where pid = 1 ; update pt_list_test set sex = '女' where pid = 1 ;select 'p1' 分区名, t.* , rowid from pt_list_test PARTITION (p1) t UNION all select 'p2' 分区名, t.* , rowid from pt_list_test PARTITION (p2) t UNION all select 'p3' 分区名, t.* , rowid from pt_list_test PARTITION (p3) t;
哈希分区 create tablespace tetstbs4 datafile '/opt/oracle/oradata/ORCLCDB/tetstbs4.dbf' size 1m autoextend on next 5m maxsize unlimited; -- 哈希分区 create table pt_hash_test( pid number(10), pname varchar2(30) ) partition by hash(pid)( partition p1 tablespace tetstbs1, partition p2 tablespace tetstbs2, partition p3 tablespace tetstbs3, partition p4 tablespace tetstbs4 ); -- 简写 create table pt_hash_test2( pid number(10), pname varchar2(30) ) partition by hash(pid) partitions 4 store in (tetstbs1, tetstbs2, tetstbs3, tetstbs4); insert into pt_hash_test (pid, pname) values (1, '瑶瑶'); insert into pt_hash_test (pid, pname) values (1500, '倩倩'); insert into pt_hash_test (pid, pname) values (null, '优优'); insert into pt_hash_test (pid, pname) values (2000, '闫闫'); commit; select * from user_tab_partitions t; select 'P1' 分区名, t.* from pt_hash_test partition (p1) t union all select 'P2' 分区名, t.* from pt_hash_test partition (p2) t union all select 'P3' 分区名, t.* from pt_hash_test partition (p3) t UNION all SELECT 'p4' 分区名, t.* from pt_hash_test PARTITION (p4) t; select 'P1' 分区名, t.* from pt_hash_test PARTITION (p1) t; select t.* from pt_hash_test PARTITION (p1) t; select t.* FROM pt_hash_test t;
组合分区 范围列表 create table pt_range_list_test( pid number(10 ), pname varchar2(30 ), sex varchar2(10 ), create_date date ) partition by range (create_date) subpartition by list(sex)( partition p1 values less than(to_date('2020-01-01' , 'YYYY-MM-DD' )) tablespace tetstbs1( subpartition sub1p1 values ('MAN' ) tablespace tetstbs1, subpartition sub2p1 values ('WOMAN' ) tablespace tetstbs1, subpartition sub3p1 values (default ) tablespace tetstbs1 ), partition p2 values less than(to_date('2021-01-01' , 'YYYY-MM-DD' )) tablespace tetstbs2( subpartition sub1p2 values ('MAN' ) tablespace tetstbs2, subpartition sub2p2 values ('WOMAN' ) tablespace tetstbs2, subpartition sub3p2 values (default ) tablespace tetstbs2 ), partition p3 values less than(maxvalue) tablespace tetstbs3( subpartition sub1p3 values ('MAN' ) tablespace tetstbs3, subpartition sub2p3 values ('WOMAN' ) tablespace tetstbs3, subpartition sub3p3 values (default ) tablespace tetstbs3 ) ) enable row movement;insert into pt_range_list_test (pid, pname, sex, create_date) values (1 , '瑶瑶' , 'WOMAN' , to_date('2019-02-02' , 'YYYY-MM-DD' ));insert into pt_range_list_test (pid, pname, sex, create_date) values (2 , '闫闫' , 'MAN' , to_date('2020-06-21' , 'YYYY-MM-DD' ));insert into pt_range_list_test (pid, pname, sex, create_date) values (3 , '雨雨' , 'WOMAN' , TO_DATE('2022-04-03' , 'YYYY-MM-DD' ));commit ;delete from pt_range_list_test where pid = 1 ;select 'p1' 分区名, t.* from pt_range_list_test PARTITION (p1) t UNION all select 'p2' 分区名, t.* from pt_range_list_test PARTITION (p2) t UNION all select 'p3' 分区名, t.* from pt_range_list_test PARTITION (p3) t;
自动分区 在Oracle Database 12.2 之前,如果使用列表分区,当插入的数据超过了分区列表值设定,则会抛出异常;而如果存在大量的列表值需要定义,则可能需要一一设置。
在12.2引入的新特性中 - Auto-List Partitioning 可以针对新的列表值,进行自动的分区创建,从而减少了维护的复杂性。
drop table enmotech purge;CREATE TABLE enmotech ( PartID integer not null , CretTm date not null , PartCD varchar2(2 ) not null ) partition by list (partcd) automatic ( partition pBJ values ('BJ' ), partition pCD values ('CD' ), partition pGZ values ('GZ' ), partition pSH values ('SH' ) );
如果这个自动分片的分区名不符合你的命名规则,可以通过DDL语句去修改变更
alter table enmotech rename partition SYS_P290 to pKM;
对于已有的分区定义,可以通过关键字 automatic 和 manual 来进行分区定义的调整
alter table PEOPLE set partitioning automatic;alter table PEOPLE set partitioning manual;
间隔分区 SQL 优化 什么是解释计划? 解释计划是一个关于SQL查询语句执行过程的文本表示。它显示了Oracle数据库如何执行查询语句,并给出了每个步骤的详细信息,如表的使用方式、索引的使用情况、连接的方法等等。通过分析解释计划,我们可以了解查询语句的执行情况,找出性能瓶颈,并针对性地进行优化。
Execute Explain Plan的使用方法 在Oracle SQL Developer中,我们可以使用”Execute Explain Plan”来生成查询语句的解释计划。首先,我们需要打开SQL Worksheet,并输入要分析的查询语句。然后,在工具栏中选择”Explain Plan”按钮,或者使用快捷键Ctrl+E来执行解释计划。在执行过程中,Oracle数据库会为查询语句生成一个执行计划,并将其显示在输出窗口中。
下面是一个示例查询语句和其对应的解释计划:
SELECT e.employee_id, e.last_name, d.department_nameFROM employees e, departments dWHERE e.department_id = d.department_idAND e.salary > 5000 ;
解释计划:
ID
操作
名称
行数
成本
0
SELECT STATEMENT
5
1
NESTED LOOPS
5
2
2
TABLE ACCESS
EMPLOYEES
5
1
3
INDEX
PK_EMPLOYEES
107
2
4
TABLE ACCESS
DEPARTMENTS
1
1
5
INDEX
PK_DEPARTMENTS
27
1
上面的解释计划使用表格的形式展示了查询语句的执行过程。每一列的含义如下:
ID:表示一个操作的唯一标识符
操作:表示每个操作的名称,比如SELECT STATEMENT、NESTED LOOPS等
名称:表示该操作对应的表的名称或索引的名称
行数:表示该操作返回的结果行数
成本:表示执行该操作需要的成本,成本越低表示执行速度越快
解释计划的每一行表示一个操作,操作之间的关系通过ID进行连接。在上面的示例中,ID为1的操作是一个NESTED LOOPS操作,它通过对EMPLOYEES表和DEPARTMENTS表进行连接来返回满足条件的结果。ID为2和ID为4的操作分别是对EMPLOYEES表和DEPARTMENTS表进行访问的操作,而ID为3和ID为5的操作则是对EMPLOYEES表和DEPARTMENTS表的主键索引进行访问的操作。
解释计划中常见的操作和符号 在解释计划中,我们会经常遇到一些常见的操作和符号。下面列举了一些常见的操作和符号,并对其进行了解释:
SELECT STATEMENT:表示整个查询语句的执行计划
TABLE ACCESS FULL:表示对表进行全表扫描,即读取表中的所有行
TABLE ACCESS BY INDEX ROWID:表示通过ROWID访问表,ROWID是一种唯一标识表中每行的标识符
INDEX RANGE SCAN:表示对索引进行范围扫描,即根据索引中的值范围来获取满足条件的结果
NESTED LOOPS:表示通过嵌套循环来执行连接操作
HASH JOIN:表示通过散列连接来执行连接操作,通常用于连接大量数据的情况
SORT JOIN:表示对结果进行排序后再执行连接操作
在实际情况中,我们可能会遇到更复杂的操作和符号,但通过对常见操作和符号的理解,我们可以初步了解查询语句的执行过程。
性能优化和解释计划 解释计划是优化SQL查询语句性能的有力工具。通过分析解释计划,我们可以找出查询语句执行过程中的瓶颈,并进行优化。下面是一些常见的优化方法:
对表添加索引:如果解释计划中出现了全表扫描的操作,说明查询语句没有使用到索引。在这种情况下,我们可以通过添加索引来提高查询性能。
优化连接操作:如果解释计划中出现了嵌套循环或Hash连接等操作,说明连接操作的性能较低。在这种情况下,我们可以考虑重新设计查询语句或调整连接顺序来提高性能。
避免排序操作:如果解释计划中出现了排序操作,说明查询语句需要对结果进行排序。在这种情况下,我们可以考虑调整查询语句或添加索引来避免排序操作。
通过不断优化查询语句,我们可以提高数据库的查询性能,提升应用程序的响应速度。