SQL优化
2009-11-06 16:51:41 来源:WEB开发网核心提示:1、选择适合的Oracle优化器(可以通过init.ora里的optimizer_mode来指定)Oracle优化器有三种:1>RULE2>COST3>CHOOSE2、选择最有效率的表名顺序:from 后面的表名是从右往左开始解析的,最右边的那张表又叫作基础表,SQL优化,如果有3个以后的表连接查询,
1、选择适合的Oracle优化器(可以通过init.ora里的optimizer_mode来指定)
Oracle优化器有三种:
1>RULE
2>COST
3>CHOOSE
2、选择最有效率的表名顺序:
from 后面的表名是从右往左开始解析的,最右边的那张表又叫作基础表。如果有3个以后的表连接查询,就需要选择
交叉表作为基础表(被其他表引用的表叫交叉表)
3、注意Where子句中的连接顺序(自右往左解析)
4、尽量多用commit
commit所释放的资源有:
1>释放回滚段中用户回复数据的信息
2>释放被程序语句获得的锁
3>减少Oracle为管理上述三种资源所需的内部花费
5、用exists /not exists 替代 in/not in
6、用索引提高查询效率
每当有记录在表中增、删、改或索引列被修改时,索引本身也会被修改,这就意味这每条insert、delete、update都会为此
多付出4、5此的磁盘I/O,但对于select所能得到的巨大好处而言这些都不值得一提(毕竟大多数表执行select语句要比insert、
update、delete要多的多),有些时候即使你为一个列设置了索引,如果你不注意以下细节,设不设置索引都要进行全表扫描):
(1)使用不等于操作符(!=、<>) ---可以用or来替代
说明:
索引只告诉你什么存在于表中,而不是告诉你什么不存在表中,所以慎用!==
例(cust_rating上有索引):
//全表扫描
select cust_id,cust_name
from customers
where cust_rating <>'aa';
//高效率
select cust_id,cust_name
from customers
where cust_rating >'aa' or cust_rating <'aa';
(2)使用is NULL 或 not is NULL
在SQL使用NULL是很麻烦的一件事,在建表时最好把你要设置索引的那个列设置成非空。因为如果被设置索引的列
在某行有NULL,就不会使用这个索引(除非此索引时位图索引)
(3)where后使用函数(只为该字段建立了索引,没有建函数索引)
(4)比较不匹配的数据类型
列age为字符,并有个索引
//索引被禁用
select s.id,s.name
from student s
where s.age = 15
改:
select s.id,s.name
from student s
where s.age ='15'
(5)LIKE 的第一个字符为 % ---这个好理解
(6)总是使用索引的第一列(多个字段做组合索引时,选用第一个字段)
如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引.
(7)避免在索引列上计算:
//低效-索引失效
select id,name
from dept
where sal *12 >2500
//高效
select id,name
from dept
where sal >2500/12 ('where sal >=2500/12 + 0.001 ' 会更好)
7、用'>='替代 '>'
8、避免在索引列上计算:
//低效
select id,name
from dept
where sal *12 >2500
//高效
select id,name
from dept
where sal >2500/12 ('where sal >=2500/12 + 0.001 ' 会更好)
9、用union替代 or (仅使用与索引列)
Oracle优化器有三种:
1>RULE
2>COST
3>CHOOSE
2、选择最有效率的表名顺序:
from 后面的表名是从右往左开始解析的,最右边的那张表又叫作基础表。如果有3个以后的表连接查询,就需要选择
交叉表作为基础表(被其他表引用的表叫交叉表)
3、注意Where子句中的连接顺序(自右往左解析)
4、尽量多用commit
commit所释放的资源有:
1>释放回滚段中用户回复数据的信息
2>释放被程序语句获得的锁
3>减少Oracle为管理上述三种资源所需的内部花费
5、用exists /not exists 替代 in/not in
6、用索引提高查询效率
每当有记录在表中增、删、改或索引列被修改时,索引本身也会被修改,这就意味这每条insert、delete、update都会为此
多付出4、5此的磁盘I/O,但对于select所能得到的巨大好处而言这些都不值得一提(毕竟大多数表执行select语句要比insert、
update、delete要多的多),有些时候即使你为一个列设置了索引,如果你不注意以下细节,设不设置索引都要进行全表扫描):
(1)使用不等于操作符(!=、<>) ---可以用or来替代
说明:
索引只告诉你什么存在于表中,而不是告诉你什么不存在表中,所以慎用!==
例(cust_rating上有索引):
//全表扫描
select cust_id,cust_name
from customers
where cust_rating <>'aa';
//高效率
select cust_id,cust_name
from customers
where cust_rating >'aa' or cust_rating <'aa';
(2)使用is NULL 或 not is NULL
在SQL使用NULL是很麻烦的一件事,在建表时最好把你要设置索引的那个列设置成非空。因为如果被设置索引的列
在某行有NULL,就不会使用这个索引(除非此索引时位图索引)
(3)where后使用函数(只为该字段建立了索引,没有建函数索引)
(4)比较不匹配的数据类型
列age为字符,并有个索引
//索引被禁用
select s.id,s.name
from student s
where s.age = 15
改:
select s.id,s.name
from student s
where s.age ='15'
(5)LIKE 的第一个字符为 % ---这个好理解
(6)总是使用索引的第一列(多个字段做组合索引时,选用第一个字段)
如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引.
(7)避免在索引列上计算:
//低效-索引失效
select id,name
from dept
where sal *12 >2500
//高效
select id,name
from dept
where sal >2500/12 ('where sal >=2500/12 + 0.001 ' 会更好)
7、用'>='替代 '>'
8、避免在索引列上计算:
//低效
select id,name
from dept
where sal *12 >2500
//高效
select id,name
from dept
where sal >2500/12 ('where sal >=2500/12 + 0.001 ' 会更好)
9、用union替代 or (仅使用与索引列)
- ››SQL Server 2008 R2 下如何清理数据库日志文件
- ››sqlite 存取中文的解决方法
- ››SQL2005、2008、2000 清空删除日志
- ››SQL Server 2005和SQL Server 2000数据的相互导入...
- ››sql server 2008 在安装了活动目录以后无法启动服...
- ››sqlserver 每30分自动生成一次
- ››sqlite 数据库 对 BOOL型 数据的插入处理正确用法...
- ››sql server自动生成批量执行SQL脚本的批处理
- ››sql server 2008亿万数据性能优化
- ››SQL Server 2008清空数据库日志方法
- ››sqlserver安装和简单的使用
- ››SQL Sever 2008 R2 数据库管理
赞助商链接