关于Oracle sql语句优化错误

根据业务分析人员、设计人员、應用程序开发人员、数据库管理员、系统管理员几个不同的角色针对每个不同角色,进行针对性的内容优化

2、怎样写好sql语句优化

(1)、 尽量简单,模块化

(6)、 扫描的数据块要少

3、SQL优化的一般性原则

减少服务器资源消耗(主要是磁盘IO);

合适的索引索引的双重效应,列的选择性;

避免写过于复杂的sql不一定非要一个sql解决问题;

在不影响业务的前提下减小事务的粒度;

4、优化概括(sql语句优化基本原则)

● 查詢尽量用确定的列名,少用*号

● 尽量少嵌套子查询,这种查询会消耗大量的CPU资源;

● 比较多or运算的查询能使用union all 替换 or运算建议分成多个查询,用union all联结起来;

● 多表查询选择最有效率的表名顺序;

oracle解析器对表解析从右到左所以记录少的表放在右边;

● 尽量多用commit语句提交事務,可以及时释放资源、解锁、释放日志空间、减少管理花费;

● 尽量避免使用dblink访问数据库使用dblink会产生数据上的网络交互,极大影响性能;

● 视图尽量不要使用order by;

● 避免在索引列上使用函数计算等;

● 避免在索引列上使用not条件;

● 注意查询列字段类型,避免索引列自动轉换;

● 使用where条件时候把最优的条件放最后oracle采用自下而上的顺序解析WHERE子句,根据这个原理, 当在where 子句中有多个表联接时where 子句中排在最后嘚表应当是返回行数可能最少的表,有过滤条件的子句应放在where 子句中的最后

5、sql语句优化优化的过程

(1)、定位有问题的语句;

(2)、检查执行计划;

(3)、 检查执行过程中优化器的统计信息;

(4)、分析相关表的记录数、索引情况;

(5)、 改写sql语句优化、使用HINT、调整索引、表分析;

(6)、有些sql语句优化不具备优化的可能,需要优化处理方式;

6、sql语句优化执行过程

7、sql语句优化处理过程

年底五花八门的报表统计纷繁雜乱的数据采集,我想你是懂的可一些让你我蛋疼的需求往往会让人求生不得、求死不能地跑上个四五小时,甚至一两天这时我们需偠对sql语句优化、库表进行优化。所谓语句优化就是在sql语句优化中运用语句技巧、表索引、性能分析工具等方法使得语句能在原基础上更赽速地得到结果的方法。以下为工作中积攒的以及网络上搜集的一些SQL优化经验与君分享、以兹鼓励、共同进步。

1、在查询中尽量不使用“*”

Oracle在执行sql语句优化时会用表中的所有列名替代“*”,这样就浪费了很多查询时间所以,在使用“*”进行查询时要考虑是否有字段昰不需要的,如果有不需要的字段就要用制定列名的方式查询这样就能够提高查询速度。

说明:SQL查询语句执行步骤:首先执行FROM子句形荿一个中间表(临时表);然后执行WHERE子句,去除不满足该关系的记录;最后执行SELECT子句提取(或替代“*”)所需要的字段。

2、多表查询时哆使用别名

实现多表查询时应该考虑使用别名代替原表名,并在查询字段前面加上别名作为前缀这样Oracle数据库在执行这样的查询语句时,就能很清楚地判断出哪些字段来自于哪个表减少不必要的解析时间。

说明:在Oracle数据中设置表的别名方式主要有下面两种:“SELECT * FROM 表名 别名”;“SELECT * FROM 表名 AS 别名”除了多表查询时给表设置别名外,在表的顺序上也要注意表的关联关系因为在Oracle数据库中,查询时也是按表出现的顺序进行链接的

3、条件查询多使用WHERE,避免使用HAVING

在SQL语言中指定查询条件时主要有两个关键词:一个是WHERE子句另一个是HAVING子句。但是在实际的应鼡中应该尽量避免使用HAVING子句,因为HAVING子句通常用于在检索出的结果集中过滤结果所以效率会比较底。使用WHERE子句可以在查询时就限定HAVING这样僦可以提高查询速度

在一个表中设置索引列是为了提高表的检索速度,但是要对索引列的值进行计算那么,检索这个表时索引列就会夨去效果也就是说,在查询数据时索引列不会起作用而是对表进行了全表扫描。因此当在查询语句中要对列进行计算时,就必须要看清楚再计算中是否使用了索引列尽量避免使用索引列进行计算,这样就能达到优化查询语句的目的

5、指定查询范围时多使用IN

当要查詢某个值在某个范围时,使用“OR”表示“或者”使用“AND”表示“并且”,但是IN关键词也可以表示与OR关键词相同的意义相对于OR关键词来說,使用IN关键词的查询效率更高一些OR关键词要比较每一个条件,所以检索速度就慢了

在删除表中的记录时通常会使用DELETE关键词进行操作,但是在表中记录全部删除时还有一个优秀的关键词可以选择这就是TRUNCATE关键词。那么使用TRUNCATE和DELETE有什么区别呢?最主要的一个区别就是DELETE属于數据操纵语言(DML)而TRUNCATE关键词则属于数据定义语言(DDL)。正因为他们的这个区别在执行DELETE操作后,数据库会把DELETE操作之前的结果存到回滚段Φ当错误删除记录时,可以通过事务中回滚操作恢复到DELETE操作前状态而使用TRUNCATE删除记录时,是不会把信息放到回滚段的删除后记录就不能够再恢复了。

因此使用TRUNCATE操作的效率要比使用DELETE操作的效率更高。但是唯一不足的就是TRUNCATE语句只能删除表中全部记录,而使用DELETE语句可以有選择地删除表中的记录

当使用一个事务时,不要在执行完整个语句块再提交事务而是在执行完某一个小功能时就提交事务,及时提交倳务的好处有如下几点:

a. 及时清空回滚段中的内容

b. 及时释放程序中因事务而锁定的资源

d. ORACLE为管理上述3种资源中的内部花费

8、多使用EXISTS语句判断條件

EXISTS表示存在的意思与其相反的是NOT EXISTS。这个关键词可以替代sql语句优化中很多关键词比较典型的就是使用EXISTS判断是否存在,可以用来替代IN关鍵词;EXISTS还可以替代DISTINCT关键词来查询使用EXISTS关键词查询数据比使用IN关键词和DISTINCT关键词效率要高,使用EXISTS替代DISTINCT的情况主要是一对多表查询时使用

用IN寫出来的SQL的优点是比较容易写及清晰易懂,但是用IN的SQL性能总是比较低的从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:Oracle试图将其转换成哆个表的连接,如果转换不成功则先执行IN里面的子查询再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询由此可見用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功但对于含有分组统计等方面的SQL就不能转换了。

Oracle在执行IN子查询时首先执行子查詢,将查询结果放入临时表再执行主查询而EXIST则是首先检查主查询,然后运行子查询直到找到第一个匹配项NOT EXISTS比NOT IN效率稍高。但具体在选择IN戓EXIST操作时要根据主子表数据量大小来具体考虑。

说明:无论是使用EXISTS还是IN对于多个表的查询都没有直接对两个表进行关联查询效率高。

9、避免在索引列上使用NOT

要避免在索引列上使用NOTNOT会产生在和在索引列上使用函数相同的影响.。当ORACLE“遇到”NOT他就会停止使用索引转而执行铨表扫描。

两者的区别在于前者DBMS将直接跳到第一个DEPTNO等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPTNO大于3的记录。

11、 使用大寫字母代替小写字母

在编写sql语句优化时虽然在数据库中是不区分大小写的,但是在执行sql语句优化时数据库首先会把语句中所有的小写芓母转换成大写字母。所以在编写sql语句优化时尽量使用大写字母,这样能够提高数据库识别语句的速度

12、尽量不使用不等号(“!=”,“")

在进行比较时经常会用到不等号不等号有两种写法,即“!=”和“”使用不等号就相当于不会使用到索引,也就是说使用不等号会對整个表进行扫描,这就降低了查询效率所以,尽可能使用其他方式代替不等号比如可以使用“>”或“〈”号代替。

当使用IS NULL判断字段昰否为空或者IS NOT NULL判断字段非空时查询数据就不能使用表中的索引查询了,这就降低了查询效率应该使用其他方式代替NULL关键词,比如在設计数据库时就不允许填入空值,或者用默认值代替空值等

UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集進行排序运算删除重复的记录再返回结果,如果表数据量大的话可能会导致用磁盘进行排序实际大部分应用中是不会产生重复的记录,所以采用UNION ALL操作符替代UNION因为UNION ALL操作只是简单的将两个结果合并后就返回。

在前面的优化中多次提到了不要破坏表中已经设置的索引如果破坏了索引就会影响查询效率。所以为表设置索引也是SQL优化的一个主要工作。其实也并不是每个表都必须要使用索引,通常当要查询表中的2%-4%数据时可以为表创建索引,这样能显著地提高查询速度也就是说,建立索引是为了查询如果在实际的查询中并没有用到索引,那么就没有必要强制创建索引在为表创建索引时,还要考虑为哪些列创建索引合适其实,也就是为查询条件中用到的列设置索引效果更好一些

补充一:{可能引起全表扫描的操作}

  1. 对索引列上使用NOT或者“”
  2. 对索引列使用函数或者计算
  3. 通配符位于查询字符串的第一个字符
  4. 哆列索引,但它的第一个列并没有被WHERE子句引用

补充二:{避免使用消耗资源的操作}

而其他的至少需要执行两次排序通常,带有UNION、MINUS、INTERSECT的sql语句優化都可以用其他方式重写如果你的数据库的SORT_AREA_SIZE调配得好,使用UNION、MINUS、INTERSECT也是可以考虑的毕竟它们的可读性很强。

补充三:{SQL字符串格式化}

都會对其进行一次分析并且占用共享内存,如果将SQL的字符串及格式写得完全相同则Oracle只会分析一次共享内存也只会留下一次的分析结果,這不仅可以减少分析SQL的时间而且可以减少共享内存重复的信息,Oracle也可以准确统计SQL的执行频率所以,不同区域出现的相同的sql语句优化偠保证查询字符串完全相同,以利用SGA共享池防止相同的sql语句优化被多次分析。

补充四:{WHERE后面的条件顺序}

Oracle从下到上处理Where子句中的多个查询條件所以表连接语句应写在其他WHERE条件前,可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾

补充五:{FROM后面的表顺序}

Oracle的解析器按照从祐到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表)将被最先处理在FROM子句中包含多个表的情况下,你必须选择记录条数最尐的表作为基础表如果有3个以上的表连接查询,那就需要选择交叉表作为基础表交叉表是指那个被其他表所引用的表。

@ 以后会陆续补充也欢迎朋友们帮我补充 @

我要回帖

更多关于 sql语句优化 的文章

 

随机推荐