sql查询优化总结

1. 影响SQL性能的原因

? 对大结果集进行高成本操作,比如排序

? 过多的I/O操作,最典型的是未建立恰当的索引,导致进行全表扫描

? 处理了太多的无用记录,如在多表查询时过滤条件位置不当,导致中间结果集包含

了太多的无用记录

? 未充分利用数据库提供的功能,如查询的并行化处理

2 排序优化(排序不只包含order by)

排序的成本十分高昂,当使用排序操作是,SQL的性能必然受到影响

? 排序过程分析

当排序结果集不是太大时,服务器在内存(排序区)完成排序操作。当排序需要更多的内存空间,服务器将进行以下处理:

1) 将数据分成多个小的集合,对每个集合进行排序

2) 服务器像磁盘申请临时空间,将排好序的中间结果写入临时段,再对另外的集

合进行排序

3) 在所有的集合都排好序后,服务器再对他们进行合并得到最终的结果;如果排

序区尺寸太小,合并无法一次完成,将分成多次进行

从上面分析可知,排序是一种十分高昂的操作,它消耗大量的CUP时间和内存,并会触发磁盘分页和交换操作

? SQL中引起排序的操作

Order by和group by 从句;distinct修饰符;union, intersect,minus集合操作符;多表连接时的排序合并连接(sort,merge,join)等

? 如何避免排序

1) 简历恰当的索引

对经常排序和连接操作的字段建立索引:在建立索引后,当服务器向这些

字段发送排序请求时,将直接进行索引而不进行排序操作。

当进行等值连接查询操作时,若建立连接的字段未建立索引,服务器进行

的是排序合并连接(sort,merge,join),连接操作的过程如下:

a) 对进行连接的两个或多个表进行全扫描;

b) 对每个表的行集分别进行全排序;

c) 合并排序结果

如果建立连接的字段已建立索引,服务器进行嵌套循环连接(nested loop

joins),该连接方式不需要任何排序,其过程如下:

a) 对驱动表进行全表扫描

b) 对返回的每一行利用连接字段值进行索引唯一扫描

c) 利用从索引扫描中返回的ROWID值在从表中定位记录

d) 合并主从表中的匹配记录

因此建立索引可避免多数排序操作

2) 用UNION ALL 替换 UNION

UNION在进行表连接后会筛选掉重复的记录,索引在表连接后会对所产生的结

果集进行排序运算,删除重复的记录再返回结果。大部分应用中是不会产生重

复记录的,最常见的是过程表与表UNION。因此,采用UNION ALL 操作符来

替代UNION,因为UNION ALL只是简单的将两个结果集合并后就返回。

2. I/O优化

过多的I/O操作会占用大量的CUP时间,消耗大量的内存和占用过多的栓锁,因此有必

要对SQL的I/O进行优化。优化I/O最有效的方式就是用索引扫描代替全表扫描。 ? 基于函数的索引

基于函数的索引(FUNCTION BASED INDEX ,简称 FBI)提供了索引列并在查询中使用这些索引的能力。FBI的实质是对查询所需的中间结果进行预处理,如果一个FBI与查询语句中的内嵌函数完全匹配,CBO(优化程序)在生成查询计划时,将自动启用索引范围扫描(INDEX RANGE SCAN)替换全表扫描(FULL TABLE SCAN)。FBI所用的函数可以是用户自己创建的,该函数越复杂,基于函数创建的FBI在SQL查询优化中的作用越明显。

? 物化视图和查询重写

物化视图是一个预计算结果集,其中通常包含聚集和多表连接等复杂操作。数据库自动维护物化视图,且随用户的要求而刷新。查询重写机制就是用数据库中的替代对象(如 物化视图)将用户提交的查询重写为完全不同但功能等价的查询。查询重写对用户透明,用户完全按常规方式编写SQL语句,CBO(优化程序)自动决定是否对用户提交的查询进行重写。

建立物化视图是使用查询重写的前提条件。

? 多表连接优化

最能体现查询复杂性的就是多表连接,多表连接往往要消耗大量的CUP时间和内存,因此多表连接查询优化是SQL查询的重点和难点。

1) 消除外部连接

通过消除外部连接,不仅使得到的查询更易于读取,而且性能也经常得到改善。 如:select A.name,B.age from A,B where A.id=B.user_id 可以改成

Select a.name ,b.age from A a ,(select id,age from B) b where

a.id=b.user_id;

2) 谓词前推,优化中间结果

多表连接的性能低下 多数是因为连接操作与过滤操作的次序不合理;大多数用户在进行多表连接时总是先进行连接操作再应用过滤条件,这导致服务器做了太多的无用功。解决这类问题的思路是:尽量将谓词往前推,使不符合条件的记录提前被帅选掉,只对符合条件的少数记录进行连接处理。这样可成倍的提高SQL性能。

3. 具体优化

? 建立索引

在where,orderby涉及的列上建立索引,避免全表扫描

? 限制结果集

1) 尽量不适用通配符:select *from A;需要几列返回几列:select column1,column2

from A;

2) 使用临时表暂存中间结果,避免多次扫描主表

? 影响优化器

1) 避免使用不兼容的数据类型,如float/int,char/varchar,binary/varBinary是不兼

容的,这样会影响优化器对SQL语句的优化

2) 优化器认为下面两个查询语句是不同的:

Select * from dual;

Select * From dual;

所以要用统一的SQL语法,注意大小写

? 放弃使用索引而进行全表扫描

1) 尽量避免在where子句中对字段进行函数或表达式操作,这将导致引擎放弃使

用索引,而进行全表扫描。如:select column from A where A/2 = 100,select column from to_date(column ,’yyyy-mm-ss’)等 。可以改为A=50;

2) 避免使用!=, <>, is null,is not null, in ,not in,or 这样也会导致引擎放弃使用索引。

不过有些优化器会对这些语句进行优化,比如 column in (‘aa’,’bb’)会被优化成 :column =’aa’ or column=’bb’

3) 避免在索引的字段中,不能用非头字母搜索,或者以%开头,因为这样将无法

利用索引,如:

SELECT * FROM T1 WHERE NAME LIKE ‘%L%’

SELECT * FROM T1 WHERE NAME LIKE ‘L%’

第一种情况不能利用索引,后一种就可以

? 多表连接

1) 多表连接时 连接条件必须写全,这样会提高查询速度

? 其他

1) 尽量使用数字类型。

字符串类型会降低查询和连接的性能,并会增加存储开销。因为引擎会逐个比较字符串的每个字符,而对于数字类型,比较一次就够了。

2) 用 EXIST 和NOT EXIST 代替 IN 和 NOT IN

前者不会产生大量的表扫描或索引扫描,性能更好

 

第二篇:SQL查询语句总结

select 语句总结

一、简单查询

(1)查询全部列

select * from 表名

(2)查询指定列

select 列名列表 from 表名 列名重命名的方法?

(3)查询经过计算的值

select 表达式 from 表名

二、选择表中的若干元组

(1)消除重复的行

在列名前加distinct关键字

(2)查询指定数量的记录

使用top n或top n percent

(3)简单条件查询

a.条件中含比较运算符 b.条件中含范围运算符 c.条件中含列表运算符 d.条件中含空值判断符 e.条件中含模式匹配符

(4)复杂条件查询

使用逻辑运算符and、or把简单条件连接起来

三、对查询结果排序

select …… from …… where ……

order by ……

四、使用compute或compute by子句* select …… from …… where ……

compute 聚合函数

select …… from ……

where ……

order by ……

compute 聚合函数 by ……

五、分组查询

select …… from ……

where ……

group by ……

having ……

六、嵌套查询

在查询语句中又包含有查询语句

七、使用union运算符合并查询结果*

select …… from ……

union

select …… from ……

八、连接查询

(1)交叉连接*

(2)内连接

(3)外连接*

(4)自连接

相关推荐