目录
1、Oracle分区类型
2、每种类型一般是用在什么场景下?
3、哪种分区类型使用的最多?为什么?
4、有没有用过组合分区?怎么搭配的?
5、分区表创建的基本语法是什么?
6、分区还有哪些不同的操作?
7、怎么去查看表格分区的信息?
8、对分区字段进行where筛选和直接读取分区内容,谁快一些?
9、索引的概念?
10、索引有哪些不同的类型?
11、不同的索引一般用在什么场景下?
12、普通索引和位图索引有什么区别?
13、索引在什么情况下会失效?
14、索引的优缺点?
15、哪些列该建立索引?哪些列不应建立索引?
16、唯一索引和主键索引有什么区别
17、怎么查看一个表格有哪些不同的索引?
18、索引中本地索引和全局索引的区别是什么?
19、oracle里面,如果有一个sql语句运行很慢,怎么办?
20、oracle有哪些常见的数据类型?
21、varchar 和 varchar2 的区别?
22、minus的含义是什么?
23、在左连接里面,如果使用and筛选和用where筛选,区别是什么?
24、左边表有身份证信息,右边也是身份证信息,查询左边有但是右边没有的身份证:
25、经常用到的函数有哪些?
26、伪列有哪些有什么用?
27、表空间怎么创建、怎么查看、有什么作用?
28、执行计划里面经常要查看哪些内容?
29、什么是视图?优点缺点是什么?
30、什么是物化视图?和视图的区别是什么?
31、存储过程由哪些代码构成?
32、什么时候写存储过程?
33、存储过程和函数的区别?
34、数据仓库是用什么方法来保存历史数据的
35、拉链表是什么结构?什么是缓慢变化维?
36、Oracle数据库的端口号是多少
37、Oracle 数据库日常维护?
38、什么是伪列,有哪几种,区别在那里?
39、如何使用ROWID去重?
40、如何分页查询?
41、SQL执行顺序?
42、如何对重复数据去重?
43、常用的SQL函数有哪些?
44、常见的分析函数(开窗函数)有哪些?
45、如何列转行、行转列?
46、分析函数和聚合函数的区别?
47、分析函数的使用需要注意什么?
48、in与not in,exists与not exists的区别以及性能分析?
49、ON和WHERE中写过滤条件的区别是什么?
50、count(*) 和 count(1)和count(列名)区别?
51、什么是同比和环比?如何用SQL实现同比环比的计算?
52、Union和union all 的区别?
53、Oracle where 子句中多个and和or时,执行顺序是怎么样的?
54、知道varchar与varchar2的区别吗?空值怎么转换及区别?
55、Delete和truncate的区别,和drop又有什么区别?
56、知道怎么授权吗?取消授权呢?
57、什么是数据字典?如何查询系统数据字典?
58、Oracle SQL语句由什么命令组成?
59、什么是事务?事务有哪些特点?
60、什么是锁,什么是死锁?
61、如果发生死锁,如何处理:
62、什么是表空间?系统常见的表空间有哪些?
63、什么是同义词?有什么作用?
64、什么是序列?常用在什么地方?
65、表分区的概念?
66、什么时候使用表分区?
67、表分区的优点和缺点?
68、如何把一张没有分区的表转化为分区表?
69、什么是游标,如何使用?
70、df游标的属性有哪些?
71、动态sql如何实现变量绑定?好处是什么?
72、如何创建存储过程?
73、存储过程参数的区别?
74、常用的异常都有哪些?
75、如何找到存储过程哪个环节执行的快慢?
76、 包的组成?
77、什么是全局变量?
78、常用的SQL语句优化?
79、优化器是什么?有哪几种?
80、表的扫描方式有哪些?优缺点是什么?
81、表的关联方式有哪些?优缺点是什么?
82、什么是并行,如何通过并行增加数据处理速度?加多少并发?
83、如何看hints 是否被调用?Hints原理
84、常见的hints优化器有哪些?
85、有两张很大的表关联,怎么做才能关联性能好?
86、大表和小表连接如何进行优化?
87、Oracle内部执行机制?
88、执行计划执行顺序
范围分区,列表分区,散列分区,组合分区
范围分区:用指定的分区键决定的范围进行分区,最为常用,分区键常采用日期。
列表分区:某列的值只有几个,可以采用列表分区。
散列分区:通过指定分区数量或编号来均匀分布数据的一种分区类型,分区数量常采用2的N次方;当列的值没有合适的条件时,采用散列分区;
组合分区:范围分区和列表分区组合;范围分区和散列分区组合,分区中的分区被称为子分区;
看具体情况:
如果需要进行数据的过期化处理,那么范围分区基本上是唯一的选择。
如果需要数据的均匀分布,那么可以考虑使用HASH分区。
如果数据的值可以很好地对应于某个分区,那么就可以考虑使用列表分区。
在上面的原则基础上,再结合性能的影响因素,来最终确定使用哪种类型的分区。
范围+列表
范围+散列
列表+散列
Create table 表名
(字段名,字段类型……)
partition by range(字段名)
(partition 子分区名 values less than (某个日期) )
添加分区,删除分区,截断分区,合并分区,拆分分区,重命名分区
select * from USER_TAB_PARTITIONS a where a.table_name = '表名';
select * from fq_emp_list where depnto=10;
select * from fq_emp_list partition(d10); -- 分区更快些
索引相当于目录,是对某些特定列中的数据进行排序,生成索引表,该列作为WHERE条件时,扫描索引列,根据ROWID快速定位具体记录,提高查询效率。
主键 唯一 普通 组合 函数 位图
分区索引分为本地和全局
唯一索引:当某列任意两行数据不相同,建立PRIMARY KEY主键和UNIQUE CONSTRAINT唯一约束时(索引自动建立)。
组合索引:当多列经常一起出现在WHERE条件中,创建索引。
位图索引:当一列有大量重复数据时建立。
函数索引:在WHERE 条件语句中包含函数或表达式时建立。
普通索引:列的内容没有什么特点,但是经常需要被进行查询创建:
位图索引:列中有非常多的重复的值时候创建。例如某列保存了 “性别”信息创建:
1. 经常需要被修改的列---重建索引
2. 数据发生了隐性的转换---新建针对该列的函数索引
3. 公式放在了等号的左边---把公式放在右边
4. 查询的时候使用!= not 空值查询
7. 组合索引没有使用第一列的列查询
8. 查询的时候,使用了非函数索引的函数
索引优点:创建唯一索引,可以保证数据库中每一行数据的唯一性;可以加快数据的检索速度;可以加速表和表之间的连接;
索引缺点:创建和维护索引要耗费大量时间;索引会占物理存储空间;对表中数据进行操作,索引也要动态维护;
建立索引:经常需要搜索、排序的列;关联字段;
不该建立索引:很少使用的列;只有很少数据值的列;定义为TEXT,IMAGE,BIT数据类型的列;
主键是不能自己独立创建,和主键约束一起创建的;
唯一可以和约束一起创建,也可以单独创建。
主键是保证字段不能空不重复,唯一只能保证不重复。
select * from user_indexes where table_name='表名';
本地索引不能创建唯一索引的类型,因为每个小的索引只能保证每个分区的数据是唯一的,不能保证整个表格的数据是唯一的。
全局索引不能创建位图索引的类型,统一管理的索引,无法对整个表格中,每个独立的分区的数据进行识别和判断。
1. 先查看执行计划,查看句子消耗的资源和内部运行的逻辑,查看语句是否运行复杂等,
查看每个子句运行的过程
2. 给数据量非常大的表格建分区(emp表为例,2个G是8000多万)
3. 给查询的字段进行索引的创建
4. 查看有没有导致索引失效的语句
5. Or会导致表格重复被读取,从而效率低下
6. sql语句频繁的对硬盘进行了读写,可以把语句写成代码块(例如存储过程)让硬盘的读写次数变少
7. sql语句可能会在客户端和服务器之间来回的进行数据的交互,这个时候也可以写成代码块减少客户端和服务器之间的交互次数
8. 还可以使用优化器里面的parallel进行sql语句的并行处理
integer number char varchar2 date blob clob
oracle里面,varchar默认就是varchar2格式
查询第一个表格有但是第二个表格没有的数据
a b
1 1
2 2
3 4
select * from a left join b on a.id=b.id and a.id=2;
3 2 1
2 2
1 null
3 null
select * from a left join b on a.id=b.id where a.id=2;
2 2
select * from a
minus
select * from b;
select * from a where id not in (select * from b);
select * from a left join b on a.id=b.id where b.id is null;
聚合函数 max min avg sum count
单行函数
数字 abs round trunc floor ceil power mod
字符串 substr concat instr replace length wm_concat translate ltrim rtrim lpad rpad
upper lower initcap
分析函数
排名 row_number rank dense_rank
平移 lag lead
逻辑函数 nvl nvl2 decode case...when... pivot
正在上传…重新上传取消
将字符串数字转换成数值型数字:to_number()
将数字类型转换成字符串:to_char()
rowid 利用唯一性进行表格数据的去重操作;索引也是使用rowid进行行数据查询的
rownum 进行表格数据的分页查询
create tablespace 名字 datafile '' size xxxM;
select * from user_tablespaces;
将表格或者分区和电脑上的数据文件进行绑定的一个数据库对象。
执行计划是一条查询语句在Oracle中的执行过程或访问路径。
执行完一条select语句后,在PLSQL执行计划窗口查看,或按F5即可查看刚执行的这条查询语句的执行计划。
或者在命令窗口输入:
SQL> explain for select * from emp
SQL> ;
Explained
SQL> select * from table(dbms_xplan.display());
主要看以下内容:
视图就是一张或多张表上的预定义查询。
作用:减少子查询的复杂性;提高运行效率;可以仅提供视图数据,提高数据安全性。视图以定义的方式存储在数据库中,不占用表空间。
视图固定为表称为物化,物化视图是当时建立视图时固定下来的数据,如果原表数据有更新,物化视图中的数据是不变的。
物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的。
普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语句的查询。这样对整体查询性能的提高,并没有实质上的好处。
create or replace procedure 名字(参数 类型)
as
声明
begin
执行
exception
异常
end;
1.使用存储过程来对sql语句进行优化,减少硬盘的读写和与服务器之间的交互次数;
2.复杂的逻辑使用存储过程;
3.一些数据库的固定操作;
4.表格的数据抽取的ETL操作。
1.返回值的区别,函数有1个返回值,而存储过程是通过参数返回的,可以有多个或者没有
2.调用的区别,函数可以在查询语句中直接调用,而存储过程必须单独调用.
函数一般情况下是用来计算并返回一个计算结果而存储过程一般是用来完成特定的数据操作(比如修改、插入数据库表或执行某些DDL语句等等)
数仓仓库保存历史数据通常是在dw层或者是hdw层 创建拉链表来保存历史数据
每次更新数据都会通过update进行逻辑删除,然后将最新的数据插入到拉链表中,并将历史数据更新成无效状态,将最新的数据更新为有效状态
拉链表:是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。
维度建模的数据仓库中,有一个概念叫Slowly Changing Dimensions,中文一般翻译成“缓慢变化维”,经常被简写为SCD。缓慢变化维的提出是因为在现实世界中,维度的属性并不是静态的,它会随着时间的流失发生缓慢的变化。这种随时间发生变化的维度我们一般称之为缓慢变化维,并且把处理维度表的历史变化信息的问题称为处理缓慢变化维的问题,有时也简称为处理SCD的问题。
处理缓慢变化维的方法通常分为三种方式:
第一种方式是直接覆盖原值。这样处理,最容易实现,但是没有保留历史数据,无法分析历史变化信息。第一种方式通常简称为“TYPE 1”。
第二种方式是添加维度行。这样处理,需要代理键的支持。实现方式是当有维度属性发生变化时,生成一条新的维度记录,主键是新分配的代理键,通过自然键可以和原维度记录保持关联。第二种方式通常简称为“TYPE 2”。
第三种方式是添加属性列。这种处理的实现方式是对于需要分析历史信息的属性添加一列,来记录该属性变化前的值,而本属性字段使用TYPE 1来直接覆盖。这种方式的优点是可以同时分析当前及前一次变化的属性值,缺点是只保留了最后一次变化信息。第三种方式通常简称为“TYPE 3”。
默认是1521
检查Oracle实例状态
检查Oracle服务进程
检查Oracle监听进程;
select+instance_name,host_name,startup_time,status,database_status from v$instance;
status是oracle实例状态必须为open。database_status是数据库状态,必须为active。
ROWID:表中的每一行在数据文件中都有一个唯一物理地址,ROWID伪列返回的就是该行的物理地址,使用ROWID可以快速的定位表中的某一行,所以可以用来查重。
ROWNUM,为结果集中每一行标识一个行号,第一行返回1,第二行返回2,以此类推,通过ROWNUM伪列可以限制查询返回的行数。
DELETE FROM 表名 别名WHERE ROWID NOT IN(SELECT MIN(ROWID) FROM 表名 别名 GROUP BY 列名)
如果想通过ROWID去重,那么在 delete 重复数据时,需要group by 表的所有字段。如果只group by 表的个别字段,那么会造成误删除。
可以用伪列rownum进行分页查询
--举例:第一页显示前5行
select ROWNUM,e.* from emp e
where rownum<=5--查询前5行,不能大于!
---第二页显示6-10
select * from
(
select ROWNUM rn,e.* from emp e
) t where t.rn>5 and t.rn<11
--第三页显示11-14
select * from
(
select ROWNUM rn,e.* from emp e
) t where t.rn>10 and t.rn<15
(1)from来自不同数据源的数据;
(2)where基于指定的条件对记录行进行筛选;
(3)group by子句将数据划分为多个分组;
(4)使用聚合函数进行计算;
(5)使用having子句筛选分组;
(6)计算所有的表达式;
(7)select 的字段;
(8)使用order by对结果集进行排序。
distinct、exists、group by 、rowid,其中distinct性能最差
字符串函数、日期函数、数值函数、NVL、decode、case when等。
聚合类分析函数:MAX(),MIN(),SUM(),AVG(),COUNT()
排名类的分析函数:RANK()1224,DENSE_RANK()1223与ROW_NUMBER()1234:--分析函数中排序
位移分析函数:LAG()与LEAD():求之前或之后的第N行
列转行:用分析函数lead/lag;用DECODE;用CASE WHEN;部分关联;
行转列:pivot(聚合函数(有数据的列) for 想转置的列名 in (该列名中的数据));
◎普通的聚合函数用group by分组,每个分组返回一个统计值,
◎而分析函数采用partition by分组,并且每行都可以返回一个统计值,
◎写法上也有区别,分析函数要带 over()。
聚合类分析函数:
---over 之后的括号里可以什么都不写
---如果写了partition by意味着分组统计
---如果加了order by 是累计统计
排名类的分析函数:
----over 之后括号里必须要有order by,
----可以没有partition by,可以不分组
LAG()与LEAD()位移类分析函数:
----over 之后括号里必须要有order by,
----可以没有partition by,可以不分组
EXISTS(查询结果集):查询结果集有记录则成立,否则不成立,可以加不等式;
IN操作符来查询其列值在指定的列表中的行,只能查询值;
性能主要还是看exists和in后面的表的数据量,数据量一致时,exists性能好。
不管是WHERE 还是ON,Oracle都会把能过滤的条件先过滤掉,再关联。但两者区别在于,如果是内关联,两种结果相同,如果是外关联,结果会不同,ON会保留主表的所有信息,而WHERE可能会过滤掉部分主表信息。
select * from dept d left join emp e on d.deptno=e.deptno and d.deptno=40;
select * from dept d left join emp e on d.deptno=e.deptno where d.deptno=40
从执行结果来说:
count(1)和count(*)之间没有区别,因为count(*)count(1)都不会去过滤空值,但count(列名)就有区别了,因为count(列名)会去过滤空值。
从执行效率来说:
(1)如果列为主键,count(列名)效率优于count(1) ;如果列不为主键,count(1)效率优于count(列名) ;
(2)如果表中存在主键,count(主键列名)效率最优;
(3)如果表中只有一列,则count(*)效率最优;如果表有多列,且不存在主键,则count(1)效率优于count(*);
环比=(现阶段 - 同一周期上一阶段)/同一周期上一阶段
同比=(现阶段 - 上一周期相同阶段)/上一周期相同阶段
可以使用LEAD和LAG函数实现
同比(相邻的年份同一个月份)和环比(同一年的相邻月份)的概念
1)UNION和UNION ALL都是将两个结果集合并为一个,但是UNION在进行表链接后会筛选掉重复的记录,Union All不会去除重复记录。fd
2)Union将会按照字段的顺序进行排序;UNION ALL只是简单的将两个结果合并后就返回。
3)从效率上说,UNION ALL 要比UNION快很多;
三个逻辑运算符优先级:NOT>AND>OR
1)varchar2所有字符都占两字节处理(一般情况下),varchar只对汉字和全角等字符占两字节,数字,英文字符等都是一个字节;
2)VARCHAR2把空串等同于null处理,而varchar仍按照空串处理;
1)在速度上,一般来说,drop> truncate > delete。
2)delete 是DML 操作,是一行行的删除数据,可以回滚,可以恢复,可以筛选数据, 如果想删除部分数据用delete,注意带上where子句;
3)truncate 是DDL操作,是删除整个表格然后重新创建一个新的,不能回滚不能筛选。
4.delete是有缓存的,truncate删除是没有缓存的
常用的系统权限集合有以下三个:CONNECT(基本的连接), RESOURCE(程序开发), DBA(数据库管理)
1)GRANT 授予权限:GRANT CONNECT/RESOURCE TO 用户名;
2)REVOKE 回收权限: REVOKE CONNECT/RESOURCE FROM 用户名;
查看对应字段的具体含义,字段类型,长度,约束,注释等。
select a.tablespace_name,--表空间名称
a.table_name,--表名
b.column_name,--字段名
b.data_type,--字段类型
b.data_length,--长度
c.comments--注释
from
user_tables a,
user_tab_cols b,
user_col_comments c
where a.table_name = b.table_name
and b.column_name = c.column_name
and b.table_name=c.table_name
and a.table_name='EMP'
数据定义语言(DDL):包括CREATE(创建)ALTER(修改)DROP(删除表)truncate(删除数据)等。
数据操纵语言(DML):包括INSERT(插入)UPDATE(更新)DELETE(删除)等。
数据查询语言(DQL):包括基本查询语句SELECT和Order By子句、Group By子句等。
事务控制语言(TCL):包括COMMIT(提交)命令) ROLLBACK(回滚)命令。
数据控制语言(DCL):GRANT(授权)命令) REVOKE(撤销)命令。
事务就是多条sql语句组成的工作逻辑单元
事务的特点:原子性、一致性、隔离性、持久性
事务对SQL语句进行分组,使它们要么全部提交 ( 这意味着它们被应用到数据库 ) ,要么全部回滚 ( 这意味着它们从数据库撤消 ) 。
只要有一条 SQL 语句执行失败,则已执行的 SQL 语句会回滚到执行之前的状态,这样就保证了数据库数据的一致性,不至于产生混乱的数据。
•原子性 Atomicity
事务必须是原子工作单元,对其进行的数据修改,要么全都执行,要么全都不执行。
强调事务的不可分割 。
例如: 银行转账, A 向 B 转账 1000 元, 要在A 账户上 减少 1000 元,同时要在 B 账户上 增加 1000 元。 并且记录一条转账记录。 要么同时执行,要么都不执行更改,以确保整个事务是一个原子工作单元。
•一致性 Consistency
事务将数据库从一个一致状态转移到另一个一致状态。
强调事务执行前后, 数据库的完整性保持一致 。
例如, 银行转账,A 向 B 账号转账 1000 元,是不允许看到 A 的账号减少 1000 , B 的账号还没来得及增加 1000 的中间状态。
•隔离性 Isolation
一个事务不会看到另外一个还未完成的事务产生的结果。每个事务就像在单独、隔离的环境下运行一样。
强调事务并发访问 , 一个事务的执行 , 不应该受到另一个事务的打扰 。
例如,一个用户正在更新员工表。其他用户不会看到对员工表所做的未提交更改。因此,在用户看来,事务似乎是串行执行的。
• 持久性 Durability
提交的事务所做的更改是永久性的。 不会因为系统失败而丢失。强调事务结束 , 数据永久保存数据库中 。事务完成后,数据库通过其恢复机制确保事务中的更改不会丢失。
锁就是某个用户在更新、修改数据时,锁定当前表或记录,不允许其他用户修改。
死锁就是两个会话,每个会话持有对方想要的资源,因争夺资源而造成的互相等待的现象。
首先要有管理员权限,然后在plsqldev工具中打开:工具-会话窗口
找到带锁的会话,点击关掉(kill)这个会话。
表空间就是一个或多个数据文件的集合,ORACLE所有的数据对象都存放在指定的表空间中,但主要存放的是表,所以称作表空间。系统常见的表空间有系统表空间、TMEP表空间、用户表自定义空间。
系统表空间:存放系统数据,例如:数据字典、视图;
TMEP表空间:存放临时缓存数据;
用户表定义空间:存放用户创建的表数据;
同义词是数据库对象的一个别名。
作用:方便其他用户访问数据库对象。
序列是用来生成连续的整数数据的对象,可以指定生成逻辑(开始整数、结束整数、是否循环)。
序列常用来作为主键中增长列。
表分区就是将表中数据在物理上存放在多个表空间,这样查询数据时不需要扫描整张表的数据文件
表的数据量特别大;表中包含历史数据,新的数据被增加到新的分区中。
优点:改善查询性能;增强数据可用性、可靠性;维护方便;
缺点:已经存在的表无法直接转化为分区,需要维护。
使用create table as select方式创建一个分区表,然后将普通表重命名,然后对新的分区表创建所需索引,重命名等。
CREATE TABLE T_NEW
()
...--带分区
AS SELECT * FROM T;
RENAME T TO T_OLD;
RENAME T_NEW TO T;
游标是指向查询结果集的一个指针,通过游标可以将查询结果集中的记录逐一取出,并在PL/SQL程序块中进行处理。
具体采用OPEN、FETCH和CLOSE语句来控制游标。或者使用FOR x in loop的方式。
游标属性:%FOUND和%NOTFOUND
%FOUND:
用于判断游标是否从结果集中提取数据。如果提取到数据,则返回值为TRUE,否则返回值为FALSE。
%NOTFOUND:
该属性与%FOUND相反,如果提取到数据则返回值为FALSE;如果没有,则返回值为TRUN。
如果动态语句是SELECT语句,可以把查询的结果保存到INTO后面的变量中。如果动态语句中存在参数,USING为语句中的参数传值。动态SQL中的参数格式是:[:参数名],参数在运行时需要使用USING传值。
sqlstr:='select ename from emp where empno=:id';---动态sql内的变量(:加变量名字)
EXECUTE IMMEDIATE sqlstr into sename using sempno;
好处是可以实现软解析
包括过程的名称、过程使用的参数以及过程执行的操作
IN表示传入参数,不可以被赋值,
OUT表示传出参数,可以被赋值,
IN OUT表示传入传出参数,可以传入值,可以被赋值,可以返回值
异常名称 |
异常码 |
描述 |
DUP_VAL_ON_INDEX |
ORA-00001 |
试图向唯一索引列插入重复值 |
INVALID_CURSOR |
ORA-01001 |
试图进行非法游标操作。 |
INVALID_NUMBER |
ORA-01722 |
试图将字符串转换为数字 |
NO_DATA_FOUND |
ORA-01403 |
SELECT INTO语句中没有返回任何记录。 |
TOO_MANY_ROWS |
ORA-01422 |
SELECT INTO语句中返回多于1条记录。 |
ZERO_DIVIDE |
ORA-01476 |
试图用0作为除数。 |
CURSOR_ALREADY_OPEN |
ORA-06511 |
试图打开一个已经打开的游标 |
用日志是用来追溯问题的,记录整个程序的运行情况,知道哪个环节报错了,记录每一步花了多少时间,判断哪一步性能不好,从而对程序进行修改和优化。
一个程序包由两部分组成:包定义和包体。其中包定义部分声明包内数据类型、变量、常量、游标、子程序和函数等元素,这些元素为包的共有元素。包主体则定义了包定义部分的具体实现。
在包定义部分声明的变量在包体里的存储过程或者函数都可使用,这个是全局的,在存储过程或者函数内部定义的只能这个存储过程或者函数使用,是局部的。
重点:SQL语句优化、索引优化、表分区优化、并行优化!
同时关注执行计划!
1.避免索引失效;
2.多使用COMMIT提交数据;
3.in,not in 用exist,not exist 替换,少用JOIN;
4.临时表;使用WITH..AS语句,对某段SQL建立临时表;拆分步骤;
5.DISTINCT 性能最差的去重,尽量用group by替代
6..使用SQL内置函数加快查询速度,例如使用decode函数替换case when;
7.避免在select 后使用'*' 符号;
8.连接和分组时先使用where条件过滤
9.避免笛卡儿积;
10.删除全表数据时TRUNCATE替换DELETE;
优化器是SQL分析和执行的优化工具,负责生成、制定SQL的执行计划。
种类:RBO基于规则的优化器;CBO基于代价的优化器(cost、time、cpu);
主要有全表扫描、索引扫描
优缺点:全表扫描可直接读取表中所有行,适合数据量小或者数据量大返回结果多;
索引扫描,查询速度快,耗费资源少,先扫描索引得到对应的ROWID,然后通过ROWID定位到具体的行读取数据;适合数据量大,返回值少的表;
嵌套循环、哈希连接、排序-合并连接
优缺点:
嵌套循环分为驱动表和匹配表,从驱动表获取一行数据,在匹配表找符合条件的行;确定合适驱动表,建立索引,执行效率会很高,数据相差大的时候出现;
哈希连接,先生成哈希函数,对两张表生成哈希值,利用哈希值建立连接。在数据量大,无索引时,比嵌套效率高,适合等值连接;
排序-合并,先排序,再连接;针对数据量大,无索引,需要排序时运用,适用非等值连接;
并行就是采用parallel技术,把一个大的任务分为若干小任务,同时启用n个进程/线程,同时处理这些小任务。通过消耗CPU资源增加数据处理速度。
适用parallel的两个条件:
1)大的任务,如全表扫描大表,小任务自己完成比派发省事
2)系统有足够的资源(cpu/io)
换句话说,并发是在系统资源充足,用户少的系统上,为了充分利用系统资源以提高任务处理速度而设计的一种技术。
查看执行计划有个PX字段代表;
在绝大多数情况下执行计划会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。此时就需要DBA进行人为的干预,告诉优化器使用我们指定的存取路径或连接类型生成执行计划,从而使语句高效的运行;
/*+ PARALLEL(表名,并行数) */ --指定开启多少个并行
/*+ INDEX(表名 索引名) */ --指定索引
/*+ FULL(表名) */ --指定全表扫描
/*+ USE_NL(表名1 表名2) */ --指定用NESTED LOOP连接
/*+ USE_HASH(表名1 表名2) */ --指定用HASH连接
/*+ USE_MERGE(表名1 表名2) */ --指定用SORT MERGE JOIN(不等式运用)/*+ LEADING(表名1 表名2) */ --指定表1作为驱动表
/*+ APPEND */ --数据直接插入到高水位上面(与insert连用)
1.首先要建立适当的索引。SQL在索引字段不要加函数,保证索引起效。如果是复合索引注意在SQL的顺序。如果已经存在索引,建议你先重建索引,因为大数据表的索引维护到了一个阶段就是乱的,一般建议重建。建立好的一般可以获得几十倍的速度提升。
2.最大数据量的表放在最前,最小的表放在最后面。SQL是从最后面开始反向解析的。
3.其次是要把最有效缩小范围的条件放到SQL末尾去。尤其是主键或者索引字段的条件。
4.为两个表设计合理的表分区,然后分别对应关联两个表的分区数据,再用union all把各个连接结果叠加起来;
将小表作为驱动表,大表作为匹配表,关联字段建索引。
1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。
2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。
3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。
4)表达式转换, 将复杂的 SQL 表达式转换为较简单的等效连接表达式。
5)选择优化器,不同的优化器一般产生不同的“执行计划”;
6)选择连接方式,ORACLE 有三种连接方式,对多表连接 ORACLE 可选择适当的连接方式。
7)选择连接顺序,对多表连接 ORACLE 选择哪一对表先连接,选择这两表中哪个表做为源数据表。
8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。
9)运行“执行计划”。
先执行缩进量最多步骤,如果缩进量一直,优先执行上面的。