欢迎来到天天文库
浏览记录
ID:6321779
大小:82.00 KB
页数:15页
时间:2018-01-10
《oracle sql语句级与策略级优化小结》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、一、基本的Sql编写注意事项·尽量少用IN操作符,基本上所有的IN操作符都可以用EXISTS代替。用表连接替换EXISTS, 通常来说,采用表连接的方式比EXISTS更有效率,RBO中适用,因为前者需要FILTER,nestedloopssemi是nestedloop连接的变种,又叫半连接。原理与nl相同,通常用于in,exist操作,这种操作join时候,通常查找到一条纪录就可以了,所以用semi表示。与semi相似的有一种叫anti,反连接,一般用于notin,notexists,也有nestloo
2、panti和hashanti两种。·不用NOTIN操作符,可以用NOTEXISTS或者外连接+替代。·Oracle在执行IN子查询时,首先执行子查询,将查询结果放入临时表再执行主查询。而EXIST则是首先检查主查询,然后运行子查询直到找到第一个匹配项。NOTEXISTS比NOTIN效率稍高。但具体在选择IN或EXIST操作时,要根据主子表数据量大小来具体考虑。·不用“<>”或者“!=”操作符。对不等于操作符的处理会造成全表扫描,可以用“<”or“>”代替。·Where子句中出现ISNULL或者ISNOTN
3、ULL时,Oracle会停止使用索引而执行全表扫描。可以考虑在设计表时,对索引列设置为NOTNULL。这样就可以用其他操作来取代判断NULL的操作。·当通配符“%”或者“_”作为查询字符串的第一个字符时,索引不会被使用。·对于有连接的列“
4、
5、”,最后一个连接列索引会无效。尽量避免连接,可以分开连接或者使用不作用在列上的函数替代。·如果索引不是基于函数的,那么当在Where子句中对索引列使用函数时,索引不再起作用。·Where子句中避免在索引列上使用计算,否则将导致索引失效而进行全表扫描。·对数据类型不同的
6、列进行比较时,会使索引失效。·UNION操作符会对结果进行筛选,消除重复,数据量大的情况下可能会引起磁盘排序。如果不需要删除重复记录,应该使用UNIONALL。·OrderBy语句中的非索引列会降低性能,可以通过添加索引的方式处理。严格控制在OrderBy语句中使用表达式。·不同区域出现的相同的Sql语句,要保证查询字符完全相同,以利用SGA共享池,防止相同的Sql语句被多次分析。·多利用内部函数提高Sql效率。·当在Sql语句中连接多个表时,使用表的别名,并将之作为每列的前缀。这样可以减少解析时间。·用
7、TRUNCATE替代DELETE,开发中不准使用。 当删除表中的记录时,在通常情况下,回滚段(rollbacksegments)用来存放可以被恢复的信息。如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况)。 而当运用TRUNCATE时,回滚段不再存放任何可被恢复的信息。当命令运行后,数据不能被恢复。因此很少的资源被调用,执行时间也会很短。·SELECT子句中避免使用'*' 当你想在SELECT子句中列出所有的COLUMN时,使用
8、动态SQL列引用'*'是一个方便的方法。不幸的是,这是一个非常低效的方法。实际上,ORACLE在解析的过程中,会将'*'依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。Count(*)10G中例外·用Where子句替换HAVING子句 避免使用HAVING子句,HAVING只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作。如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。·需要注意的是,随着Oracle的升级,查询优化器会自动对
9、Sql语句进行优化,某些限制可能在新版本的Oracle下不再是问题。尤其是采用CBO(Cost-BasedOptimization,基于代价的优化方式)时。二.跟踪和分析系统及SESSION级的SQL:跟踪SQL语句SQLtrace工具收集正在执行的SQL的性能状态数据并记录到一个跟踪文件中.这个跟踪文件提供了许多有用的信息,例如解析次数.执行次数,CPU使用时间等.这些数据将可以用来优化你的系统.设置SQLTRACE在会话级别:有效ALTERSESSIONSETSQL_TRACETRUE设置SQLTRA
10、CE在整个数据库有效仿,你必须将SQL_TRACE参数在init.ora中设为TRUE,USER_DUMP_DEST参数说明了生成跟踪文件的目录跟踪会话和系统跟踪跟踪自己的会话或者是别人的会话跟踪自己的会话很简单Altersessionsetsql_tracetrue
11、falseorexecdbms_session.set_sql_trace(TRUE);如果跟踪别人的会话,需要调用一个包execdbms_system.set
此文档下载收益归作者所有