--创建存储过程
Create or replace procedure ins_p(cnt int) as Declare X int; Begin For x in 1 .. cnt loop Insert into tx values(x, 'hello'); Insert into ty values (x, 'world'); End loop; Commit; End;
--每个表插入100万数据
call ins_p(1000000);
--分析一下下面这个相关子查询
select * from tx a where exists (select * from tx b where a.id = b.id and a.name = b.name and b.ID <= 10)
执行一下这个SQL语句,记录下他的执行号3304:
查看其执行计划:
使用SQL_ET存储过程查看该SQL各操作符的执行时间:
--从操作符的执行时间可以看出:时间主要消耗在对TX表和TY表的全表扫描上了,我们有针对性的创建两个索引,将全表扫描转化为索引扫描即可。
Create index txl01 on tx(id); Create index tyl01 on ty(id);
--创建索引后,我们再来看看执行计划:
--再来看这个SQL各操作符的执行时间
三、 应用优化
1. 会话管理
在SQL SERVER数据库中鼓励开发人员每执行一个SQL就创建一个会话,这样能够提高性能,但在DM和ORACLE中这种应用的会话管理在性能上就是一个灾难,DM中一个会话足够能干,不需要为每一个SQL创建一个会话来执行,移植类似的SQL SERVER的应用需要注意。
2. 索引优化
索引对数据库I/O的影响十分巨大。如果通过索引来访问数据库,可以大大减少对大型表的全表扫描,从而减少I/O的开销。索引的使用通常能够提高SELECT,UPDATE以及DELETE语句的性能,但会降低INSERT语句的性能,因此索引并非是越多越好,使用索引应该遵循以下原则:
仅当要通过索引访问表中很少的一部分行(1%~20%)
如果要处理表中的多行,而且可以使用索引而不用表
不能利用索引的场合:
索引列上有函数(确定性的函数可以创建函数索引)
索引列存在隐式类型转换
3. 索引列选择率差,不如全表扫描
仅查询需要的列
很多没有经验的程序员为了贪图一时的方便喜欢使用SELECT * 来查询,这样实际上会带来很多额外的网络、IO开销,严重的时候会引发灾难。给大家分享一个案例:
某应用有条SQL计划非常好,索引都利用上了,但是运行非常慢:
SELECT * FROM MANALOG_DATA_SCADA WHERE ……
原因是:该表有1441列,这个业务只需要其中的3个列,却写了SELECT * 带来不必要的网络和IO的开销,导致性能低下。
优化方法:修改SQL语句,只查询需要的列:
Select c1,c2,c3 from MANALOG_DATA_SCADA where ………
更多精彩尽在2014年4月10日-12日在北京五洲皇冠国际酒店举办的第五届中国数据库技术大会,敬请期待!