oracle实践

一、空值判断,空值转换

         使用is null、is not null,判断是否是空值。使用nvl(exp1,exp2)将空值转换为其他值。

         exp1表示可能为空的字段,exp2表示转换成什么值。

二、列转行 pivot

         语法:select * from table pivot (聚合函数 for column in (‘常量值1’,’常量值2’));

         相当于对column字段进行分组处理,聚合函数为需要统计的字段值。

select * from (select * from t_merchant_product_trade_summary where mcht_id = '366521058121455')

pivot (sum(amount_summ)  for trade_type in ('微信支付' wx,'支付宝支付' ali));

三、行转列 unpivot 待定

         语法:

四、将某一列的值进行字符创拼接输出 listagg

         语法:listagg(column,'分隔符') within group(order by 排序字段)

         查询商户下所有的分店id,并且分店id已‘;’来分割

select mcht_id,listagg(branch_id,';')within group(order by mcht_id) from t_branch_info where mcht_id='821330156910869'

group by mcht_id;

五、批量插入

        Insert all

        into table () values ()

        into table () values ()

        …

        select 1 from dual;

六、NUMBER的使用

         NUMBER(precision,scale)的说明

        presion表示从左边第一个不为0的有效位最大为precision,如果没有指定默认是38位

        scale表示小数位最多为scale,正数表示精确到小数点右边位数,负数表示精确到小数点左边位数,默认是0

        s   >   0 ,精确到小数点右边s位,并四舍五入。若s>p,小数点右侧至少有s-p个0填充(必须从小数点处开始并连续),然后检验有效位是否   <=   p。

        s   <   0 ,精确到小数点左边s位,并四舍五入。然后检验有效位是否   <=   p   +   |s|。

        s   =   0 ,此时NUMBER表示整数。

        NUMBER:等价于double,对小数位没有明确要求的情况下使用。

        NUMBER(2): 最大两位整数,定义整数使用。

        NUMBER(7,2): 有效位数7位,小数位2位。用于指定小数位数的情况。

七、对于查询的列的说明

        将查询的列看做是一个变量,可以查询原始列,也可以对列进行运算,对列使用函数等操作

八、distinct去除重复行

         Distinct 作用其后所有的列,group by 也是作用于其后所有的列。

九、常用函数

         字符函数:upper,lower,concat ,length

        字符串截取函数substr(‘hello’, 1, 3):表示从第一个字符开始截取,一共截取3个字符。hel

        替换函数replace(‘aba123’,’a’,’A’):替换字符串中出现的字符或字符串AbA123

        去空格函数trim(‘ ab ’):去除首尾空格

        数值函数

        日期函数:last_day(date):获取当前月的最后一天;add_months(date, int):对日期date加或者减多少个月。

        转换函数:to_char,to_date,to_number。

select to_char(sysdate, 'yyyy-MM-dd hh:mi:ss') from dual;
select to_date('2019-05-07 10:57:12','yyyy-MM-dd hh:mi:ss') from dual;
select to_number('1234') + to_number('4321') from dual;

        通用函数:nvl,decode,case when then end,trunc;

nvl(exp1,exp2):对exp1进行控制判断,如果为空取exp2的值,否则去exp1的值。

decode(val,if1,then1,if2,then2,else):当val值为if1时返回then1,条件都不满足时返回else值。

select decode(8, 1, 2, 2,3, 4) from dual; 值为4

模式一:case val when a then A when b then B else C end:当val的值为a时返回A,为b时返回B,都不满足时返回C。

select case 8 when 1 then 2 when 2 then 3 else 4 end from dual; 值为4

模式二:case搜索函数:

case when sex = '1' then '男'

     when sex = '2' then '女'

     else '其他' end



trunc(val, digit):截取函数,不进行四舍五入。val表示要截取的值,digit表示保留的精度。

十、分组函数

        count,avg,max,min,sum。分组函数会省略列中的空值,可用nvl函数强制对空值进行处理

        如:select avg(nvl(comm,0)) from emp;

十一、group by 子句

        group by 作用于其后的所有字段,即可对多个字段进行分组,分组的顺序按字段出现的顺序。当使用group by 子句后,select 后的字段必须是分组字段或者是分组函数。需要注意的是如果没有group by 子句那么不允许列和分组函数混合使用

十二、having 子句

         一般用于分组后的过滤

十三、多表查询连接方式

         1.笛卡尔集 结果集数量为count(A)*count(B)

                   Select * from A,B;

         2.等值连接(内连接)同时满足连接条件才显示

                   Select * from A,B where A.id=B.aid; 等价于

                   Select * from A inner join B on A.id=B.aid;

         3.自连接 同表做关联

                   Select * from A a1 inner join A a2 on a1.pid=a2.pid;

         4.左连接 以左表(A)为主表,左边记录都显示,右表记录满足连接条件显示

                   Select * from A left join B on a.id=B.aid;

         5.右连接 以右表(B)为主表,右表记录都显示,左表记录满足连接条件显示

                   Select * from A right join B on a.id=B.aid;

         6.全连接 结合了左连接和右连接,等价于左连接和右连接的并集union

                   Select * from A full join B on A.id=B.aid; 等价于

                   Select * from A left join B on a.id=B.aid;

                   Union

                   Select * from A right join B on a.id=B.aid;

十四、集合操作

         集合操作是对查出来的多张表进行的处理。前提是这多张表具体相同的结构(字段)

         1.union 并集,自动去重

         2.union all 并集 不去重

         3.intersect 交集 只显示重复的内容

         4.minus 差集 只显示对方没有的(和顺序相关)

十五、子查询

         1.单行子查询 子查询返回的一行记录并且是一个值

       select * from emp where sal > (select sal from emp where empno = 7566);

        2.多行子查询 表示返回多条记录,此时要使用到关键字in,any(返回记录的任意一个),all(返回记录的所有)

        3.topN查询 类似于最多最少的场景。根据查询条件查询前N条记录,使用到了排序+rownum

select * from emp where rownum<=5 order by sal desc

        4.分页查询

        常用:select * from (select rownum rn,t.* from t_merchant_info t where rownum <= 30)

where rn > 20;

        方式二:select * from (select rownum rn,t.* from t_merchant_info t)

where rn > 20 and rn <= 30;

        5.exists关键字 使用语法:where exsits(相关子查询)

        相关子查询:指的是子查询查询条件依赖于外部父查询,因此需要根据外部查询的每一条记录来进行子查询。当子查询返回结果为真,那么这条记录放入结果集中。

        Exsits关键字后的子查询只返回逻辑值true或false。子查询有结果集返回true,无结果集返回false。

        not exists 和exists功能相反。

        exists和in的区别

        exists后面接相关子查询。in后面接不相关子查询(子查询不依赖于父查询).

        exsits是外层表驱动内层表,适用于外层表较小的场景。in 是内层表驱动外层表,当子查询结果集较小时使用in。

十六、高级查询

1)递归查询

        SELECT … FROM + 表名
        START WITH + 条件1
        CONNECT BY PRIOR + 条件2
        WHERE + 条件3

使用场景:用户表示树状结构的递归查询(比如含parent_id字段),比如省市区网点等。

条件1表示起始条件,可以是根节点或者叶子结点。条件2表示连接的条件,prior所在侧表示前一条记录。

示例一:自顶向下查询,以REGION_ID = '2000000007'作为开始行(根结点)(二级机构),PRIOR侧指的前一条记录即该二级机构,条件表示查询父机构id是2000000007的机构即所有的三级机构。如此循环递归每一个三级机构又作为开始行继续查询四级机构,直到查询完所有的机构信息。

select REGION_ID, REGION_NAME, ORG_LEVEL, REGION_CODE
  from T_REGION_INFO t
 start with t.REGION_ID = '2000000007'
CONNECT BY PRIOR t.REGION_ID = t.PARENT_ID

示例二:自底向上查询,REGION_ID = '4000000887'作为开始行(叶子结点)(四级机构),递归向上查找根节点。

select REGION_ID, REGION_NAME, ORG_LEVEL, REGION_CODE
  from T_REGION_INFO t
 start with t.REGION_ID = '4000000887'
CONNECT BY t.REGION_ID = PRIOR t.PARENT_ID

十七、oracle数据类型

         Char固定字符串,长度不可变,速度比varchar2快。

         Varchar2可变字符串,长度根据实际长度调整,用的最多。

         Number:见上述解释

         Date:时间精确到秒

        Timestamp:时间精确到秒后6位

十八、sql执行顺序

        

十九、DDL语言

1.创建表

              Create table student(

                Sid number(10),

                Sname varchar2(10)

                );

       使用子查询创建表:

       create table myemp as select * from emp;

         2.修改表

       Rename student to student1;

         3.删除表

       Drop table student;

         4.添加字段

       Alter table student add age number(5);

         5.修改字段

       Alter table student modify age number(10);

Alter table table2 rename column result to result2;

         6.删除字段

         Alter table student drop column age;

二十、DML语句

       Insert、update、delete

       Insert表间拷贝数据:

       Insert into dept1(id,name) select deptno,dname from dept;

二十一、约束

       约束就是对插入数据的各种限制。

       Not null:非空约束

       Unique: 唯一约束(空值除外)

       Primary key: 主键约束 唯一非空

       Check: 条件约束,插入的条件必须满足给定的条件

       如:age NUMBER CHECK(age BETWEEN 0 AND 150)

       Foreign key: 外键约束

       ON DELETE CASCADE:级联删除 指的是删除主表时,关联的外键的记录也被删除了。

       一般来说,在创建表时就添加约束。

       创建表后添加约束:

       以上两张表中没有任何约束,下面使用 alter命令为表添加约束

例子:person和book关系时一对多

1、 为两个表添加主键:

person表pid为主键:

ALTER TABLE person ADD CONSTRAINT person_pid_pk PRIMARY KEY(pid) ;

book表bid为主键:

ALTER TABLE book ADD CONSTRAINT book_bid_pk PRIMARY KEY(bid) ;

2、 为person表中的tel添加唯一约束:

ALTER TABLE person ADD CONSTRAINT person_tel_uk UNIQUE(tel) ;

3、 为person表中的age添加检查约束:

ALTER TABLE person ADD CONSTRAINT person_age_ck CHECK(age BETWEEN 0 AND 150) ;

4、 为book表中的pid添加与person的主-外键约束,要求带级联删除

ALTER TABLE book ADD CONSTRAINT person_book_pid_fk FOREIGN KEY (pid) REFERENCES person(pid) ON DELETE CASCADE ;

二十二、索引

         索引的创建:create [unique] index index_name on table_name (column);

         索引的删除:drop index index_name;

         查看全部索引:select * from user_indexes;

         唯一索引:索引列值可以为空,但只要有值则必须唯一。

         非唯一索引:即普通所以,对唯一性没有要求。

         两者区别:执行计划的差异。通过唯一索引查找记录时使用的是index unique scan操作,直接定位到相应的叶子数据块,返回rowid。通过普通索引查找记录时,使用的是index range scan操作,沿着索引树叶子结点水平扫描,返回符合条件的索引值的rowid列表。

         Oracel默认的索引实现原理:B树索引,B树是一棵平衡树,每个结点的左子树和右子树的高度差不超过1。

         B树索引的创建和查找

         创建是从下往上,查找是从上往下。

        1.要建索引先排序 ,所以索引其实是有序的,对索引列排序。

        2.列值入块成索引,索引块就是这么来的。

        3.填满一块接一块,数据量增大在索引的体现,就是叶子块横向扩展。

        4.同级两块需人管,叶子块有2个或以上时候,就需要有一个老大来管理多个叶子块,这个老大块里放的是每个叶子块的指针,所以索引的高度不容易变得特别大也是这个道理。

        B树索引的特点:

        索引高度较低:50w数据量的查询效率和500w的可能是一样的。

        索引存储列值:对聚合函数使用索引,提升性能。避免回表,提升性能。

        所有本身是有序的:能够消除排序如order by

         Blevel:branch level 分支层数,即不包含叶子结点层。千万级的数据blevel也就2层,所以通过索引查找数据是非常快的。

        理想状态下,一个高度为3的主键索引B+tree树,至少可以存多少数据呢?(个人理解)

        oracle:假设主键为BIGINT,占8个字节,rowid占8个字节,一个指针通常也为4或8个字节,那一个块为8k,数据即 8k/16b = 500条,一个2级的块就能存500个指针,总数就是500*500*500 = 1.25亿条数据。

        组合索引:索引排序(第一列先排序,第二列后排序)

        在等值查询情况下,组合索引的列无论哪列在前,性能都一样。

        组合索引的两列,当一列是范围查询,一列是等值查询时,等值查询在前,范围查询在后更高效。

        创建索引:创建索引有排序和锁表的动作,切记在业务高峰期操作。

        优劣:提升查询效率;插入,删除,更新变慢。

二十三、SQL优化

         合理使用索引

         最左前缀,利用组合索引的前置列查询

         当业务需要返回列极少时,避免使用select *,消除TABLE ACCESS BY INDEX ROWID回表动作改进性能,直接返回索引字段。如果字段不够可以考虑组合索引,一般不超过3个。如果一定有回表动作,聚合因子越小的索引性能越高。(不用跨多个数据块去匹配数据),如果需要优化聚合因子,需要重组表记录。

         表关联的时候使用小表连接大表

         使用exist代替in

         优化表字段数量,提升全表扫描性能

         统计时使用聚合函数,对列合理设置索引能提升性能

         Union all 通常比union更高效

二十四、执行计划

Oracle B-Tree 索引的结构、特点及索引扫描方式 | coderbee笔记

ORACLE树状索引详解(图摘取《收获不止oracle》)_u010692693的专栏-优快云博客

(Oracle)看懂Oracle执行计划(转载) - ThinkDifferent - 博客园

         执行计划可以看做是一条SQL语句的执行过程,对于SQL的语句的优化一般从看懂执行计划开始。通过创建索引或者修改SQL语句优化语句。一般cost越小,sql性能越好,但最终应该以测试结果为准。

  1. 执行顺序的原则:从右到左,从上到下

        Sql语句+F5 或者

        Explain plan for sql语句;

        Select * from table(dbms_xplan.display);

      2.表的访问方式:

        TABLE ACCESS FULL(全表扫描)

        TABLE ACCESS BY ROWID(通过ROWID的表存取)

        TABLE ACCESS BY INDEX SCAN(索引扫描)

       3.索引的扫描方式:CBO(Cost-base optimization)

        INDEX UNIQUE SCAN:索引唯一扫描,出现在索引的“所有列”上使用“等于”条件的 SQL 中,最多返回一行结果。

        INDEX RANGE SCAN:索引范围扫描

        在唯一索引列上使用了范围操作符(如:>   <   <>   >=   <=   between)

        在组合索引上,只使用部分列进行查询(查询时必须包含前导列,否则会走全表扫描)

        对非唯一索引列上进行的任何查询

        INDEX FULL SCAN:索引全扫描,按顺序扫描索引中的所有叶节点块。可以从左往右扫描,也可以从右往左扫描。是有序的

        INDEX FULL SCAN(MAX/MIN):使用max/min函数时可以走索引全扫描,因为索引时有序的,所有只需要看叶子块的最右边和最左边就行。

        INDEX FAST FULL SCAN:索引快速全扫描,并行读取多个数据块进行扫描,扫描得到的结果是无序的。使用count(*)/avg/sum聚合函数可以走索引快速全扫描,因为无需有序,需要保证索引的列不为空。

        INDEX SKIP SCAN:索引跳跃扫描,出现在复合索引中,对非前缀列上使用任意比较条件的 SQL 中。Oracle 在扫描时,会扫描所有的 branch block,然后对 branch block 中的每一个值,都会去扫描 leaf block。适合于复合索引的前缀列不同值个数很少的情况,否则其扫描成本非常高。场景少

       4.表的连接类型:

       内连接INNER JOIN

       外连接OUTER JOIN(LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN)

       5.表的连接方式:

区分哪张是驱动表,哪张是匹配表,一般驱动表为小表,匹配表为大表。

就是两个表获得满足条件的数据时的连接过程。主要有三种表连接方式,嵌套循环(NESTED LOOPS)、哈希连接(HASH JOIN)和排序-合并连接(SORT MERGE JOIN)

        6. 说明:

        对于表的连接顺序,多数情况下使用的是嵌套循环,尤其是在索引可用性好的情况下,使用嵌套循环式最好的,但当ORACLE发现需要访问的数据表较大,索引的成本较高或者没有合适的索引可用时,会考虑使用哈希连接,以提高效率。排序合并连接的性能最差,但在存在排序需求,或者存在非等值连接无法使用哈希连接的情况下,排序合并的效率,也可能比哈希连接或嵌套循环要好。

二十五、存储过程

CREATE OR REPLACE PROCEDURE gwj_test

IS

BEGIN

for i in 1 ..164

loop

    insert into t_gwj_stall_reservation (AREA_ID, AREA, STALL, STATUS, RENT_START_TIME, RENT_END_TIME, PRICE, IS_LOCK, MONTH_PRICE, QUARTER_PRICE)

values (2, '衣裳街B区', '红' || i, '0', null, null, '3', null, '11', '32');

end loop;

commit;

END;

调用:call gwj_test();

二十六、取分组后的最值

        ROW_NUMBER() OVER(PARTITION BY 列A ORDER BY B DESC) rn:对表中某个字段进行分组,并且根据某个字段排序,然后去每个分组的第一条数据。

        PARTITION BY index_etc:表示对index_etc分组

        ORDER BY trade_time DESC:表示对trade_time降序排列

        WHERE rn = 1:表示去分组后的第一条数据

select *

  from (select ROW_NUMBER() OVER(PARTITION BY index_etc ORDER BY trade_time DESC)

   rn,t_untp_trade_list_deduction.*

              from t_untp_trade_list_deduction)

 where rn = 1;

二十七、查看表占用的存储空间

        segment_name必须要大写!

select t.owner,t.segment_name, t.segment_type, sum(t.bytes / 1024 / 1024) "占用空间(M)"

from dba_segments t

where t.segment_type='TABLE'

and t.segment_name='T_AGGREGATE_PAYMENT_ORDER'

group by OWNER, t.segment_name, t.segment_type;

二十八、数据库迁移

        使用exp/imp命令完成。在用户oracle中完成。dump文件中包含了表中的数据和表结构信息。

        1.登录到linux服务器,切换用户su – oracle。

注意符号-,否则无法使用oracle配置的环境变量,导致exp/imp命令不可用,需要进入到bin目录。

        2.将表数据导出为dmp文件。

按表导入:exp username/password@实例名file=dmp输出路径 tables=’table1,table2’

exp zjtest/zjtest@ora11g file=/project/daochu.dmp tables='t_merchant_info,t_refund_order'

按用户导入:exp username/password@实例名file=dmp输出路径 owner=username

完全导出:exp username/password@实例名file=dmp输出路径 full=y 这种需要username为dba权限。

        3.在目标数据库中创建用户。

登录到linux服务器,切换用户su – oracle

以管理员登录:sqlplus / as sysdba

创建用户:CREATE USER c##dev IDENTIFIED BY 13579; 需要以c##或C##开头,默认使用的表空间为users

赋予dba权限:GRANT CONNECT,RESOURCE,DBA TO c##dev;

用新用户登录:sqlplus c##dev/13579

        4.导入dmp文件。

imp username/password@servicename file=dmp路径

imp c##dev/13579@orcl file=/project/prepay/daochu.dmp ignore=y full=y

全部导入:full=y

igore=y: 如果表结构存在则不创建表结构,如果表结构不存在则创建表结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值