时间:2021-07-01 10:21:17 帮助过:43人阅读
oracle数据库 无 /**********Oracle中的SQL性能优化****************/ 村长 12800258851.索引方面1.1 应该尽量避免在where子句中对字段null进行判断,否则否则将导致引擎放弃使用索引而进行全表扫描例子:如 select id from t where num is null可以在num上设置
oracle数据库 <无>/**********Oracle中的SQL性能优化****************/ 村长 1280025885
1.索引方面
1.1 应该尽量避免在where子句中对字段null进行判断,否则否则将导致引擎放弃使用索引而进行全表扫描
例子:如 select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
1.2 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
1.3 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:(使用union all来查询)
select id from t where num=10
union all
select id from t where num=20
1.4 in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
1.5 下面的查询也将导致全表扫描: 对于大量模糊查询使用lucene等查询
select id from t where name like '%abc%'
若要提高效率,可以考虑全文检索。
1.6 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num
1.7 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2
1.8 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
1.9 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
1.10 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致
1.11 不要写一些没有意义的查询,如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
create table #t(...)
1.12 很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)\
1.13 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
1.14 并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。据估计为20%
1.15 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
2.表中的字段设计
2.1 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
2.2 尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
2.3 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
2.4 尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)
2.5 避免频繁创建和删除临时表,以减少系统表资源的消耗。
2.6 临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
2.7 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
3.表结构拆分与优化
3.1
/*********************oracle数据库sql语句**********************/
1.创建表
/***********
注意的地方:
1.尽量使用number类型,或者varchar
2.如果是主键,或者唯一约束,默认带有索引,可以提高性能
3.如果能设置默认值,最好设置默认值为0
***********/
1.1 oracle普通建表语句
create table user(
id number(6),
name varchar(20),
sex number(1)
)
1.2 不带约束名的建表语句
create table user(
id number(6) primary key, --主键
name varchar2(20) not null, --非空
sex number(1),
age number(3) default 18,
birthday date,
address varchar2(50),
email varchar2(25) unique, --唯一
tel number(11),
deptno number(2) references dept(deptno) —外键
);
1.3 带约束名的建表语句
create table user(
id number(6) constraint id_pk primary key,
name varchar2(20) constraint name_nn not null,
sex number(1),
age number(3) default 18,
birthday date,
address varchar2(50),
email varchar2(25) constraint email_uqe unique,
tel number(11),
deptno number(2) constraint dept_deptno_ref references dept(deptno)
);
1.4 带约束列的sql语句
create table userInfo (
id number(6),
name varchar2(20),
sex number(1),
age number(3) default 18,
birthday date,
address varchar2(50),
email varchar2(25),
tel number(11),
deptno number(2),
constraint id_pk primary key (id),--也可以两个以上,联合主键
constraint dept_deptno_ref foreign key (deptno) references dept(deptno),
constraint emial_name_uqe unique (email, name)
);
1.5 alert模式
oracle 添加一个字段
alter table user add(msn varchar2(20));
oracle 修改一个字段的长度
alter table user modify(msn varchar2(25));
oracle 删除一个字段 不建议做(删了之后,顺序就变了。加就没问题,应为是加在后面)
alter table user drop(msn);
修改表名 很少修改
rename user to student
删除表
drop table user;
删除主键
alter table user drop constraint id_pk;
添加主键
alter table user add constraint id_pk primary key (id);
/*******
主键和唯一索引的区别:
1、主键每张表只可以有一个,唯一索引可以有多个
2、主键列不允许有NULL数据,唯一索引可以
3、主键列一定是唯一索引列,唯一索引列不一定是主键列
*******/
1.6 创建索引
普通索引:create index idx_dpt_dname on dept(dname);
联合索引:create index idx_dept_dname_deptno on dept(dname, deptno);
唯一索引: create unique index idx_emp_ename on scott.emp(ename);
反向键索引: create index on scott.emp(empno) reverse;
位图索引: create bitmap index idx_emp_name on scott.emp(dname);
1.7 创建索引
create sequence seq;
select seq.nextval from dual;
insert into tab values(sql.nextval, ‘id1’);
创建索引
create sequence seqtab
start with 2 –从2开始
increment by 3—每次加3
nomaxvalue—没有最大值
minvalue 1—最小值1
nocycle—不循环
nocache;--不缓存
2 创建表空间
2.1创建表空间
create tablespace HooMS
datafile 'E:\HooMS.dbf'
size 5M
autoextend on next 2M maxsize 10M;
2.2创建用户、分配可以操作表空间
create user hoo
identified by hoo
default tablespace HooMS
temporary tablespace temp;
2.3创建表空间
create tablespace myMS
datafile 'c:\myMS.dbf'
size 1M
autoextend on;
2.4扩展表空间--修改表空间大小
alter database
datafile 'c:\myMS.dbf'
resize 2M;
2.5扩展表空间--添加数据文件
alter tablespace myMS
add datafile 'c:\myMS_2.dbf'
size 1M;
2.6设置dbf文件自动增长
alter database
datafile 'c:\myMS_2.dbf'
autoextend on next 2M maxsize 4M;
2.7表空间重命名
alter tablespace myMS
rename to hooMS;
2.8分离表空间(脱机)
alter tablespace hooMS
offline temporary;
2.9归档模式下脱机
alter tablespace hooMS
offline immediate;
2.10使表空间联机
alter tablespace hooMS online;
2.11删除无数据的表空间
drop tablespace hooMS;
2.12删除带数据的表空间
drop tablespace hooMS
including contents;
3.oracle 查询sql语句
4.oracle 插入sql语句
4.1 插入所有字段
insert into user values ("id","name",0)
/*** 如果有日期需要修改日期格式
4.2 插入部分字段
insert into user (id,name,sex) values("id1","name1",0)
4.3 如果插入null
insert into user (id,name,desp) values("id1","name1",null)
/*** 如果查询null 怎么写
错误 select * from user u where u.desp = null
正确 select * from user u where u.desp is null
5.分组语句
6.oracle 数据库事物处理
7.oracle 数据库数据完整性
oracle PLSQL
8.0 简单存储过程
语法:
创建存储过程基本语法:
create procedure 过程名(参数1…)
is
begin
执行语句;
end;
例子:如果向user表中插入一条记录
create procedure adduser
is
begin
insert into user(id,name) values("5","user5")
end;
例子:使用存储过程删除一条记录
create procedure proc2(in_empno number)
is
begin
delete from emp where empno=in_empno;
end;
存储过程的调用
1.sqlplus 控制台
execute/call 过程名(参数1…);
2.java中使用callableStatement接口
/*****建议
当定义变量是时,建议用v_作为前缀v_sal
当定义常量constant是时,建议用c_作为前缀c_sal
当定义游标cursor时,建议用_cursor作为后缀emp_cursor
当定义例外时,建议用e_作为前缀e_error
块(编程):过程(存储过程)、函数、包(包体)、触发器。块是他们的基本编程单元。
******/
9 oracle 触发器
创建触发器基本语法:
create [or replace] trigger触发器名
{before | after}
{insert|delete|update[of 列1[,列2…]]}
on [方案名.]表名
[for each row]
[when 条件]
begin
--触发器内容
end;
/*********sql常用语句**************/
1.常用sql
1.1 查询Oracle正在执行的sql语句及执行该语句的用户
SELECT b.sid oracleID,
b.username 登录Oracle用户名,
b.serial#,
spid 操作系统ID,
paddr,
sql_text 正在执行的SQL,
b.machine 计算机名
FROM v$process a, v$session b, v$sqlarea c
WHERE a.addr = b.paddr
AND b.sql_hash_value = c.hash_value
1.2 查询oracle当前被锁对象
SELECT l.session_id sid,
s.serial#,
l.locked_mode 锁模式,
l.oracle_username 登录用户,
l.os_user_name 登录机器用户名,
s.machine 机器名,
s.terminal 终端用户名,
o.object_name 被锁对象名,
s.logon_time 登录数据库时间
FROM v$locked_object l, all_objects o, v$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid
ORDER BY sid, s.serial#;
1.3 查询oracle 执行过的sql
SELECT * FROM V$SQLAREA T ORDER BY T.LAST_ACTIVE_TIME DESC;