快捷搜索:

SQL语句性能调整(1) - SQL语句

一、 索引(INDEX)应用的问题

1. 索引(INDEX),用照样不用?这是个的问题。

是全表扫描照样索引范围扫描主要斟酌SQL的查询速率问题。这里主要关心读取的记录的数目。根据DONALD K .BURLESON的说法,应用索引范围扫描的原则是:

对付数据有原始排序的表,读取少于表记录数40%的查询应该应用索引范围扫描。对读取多于表记录数40%的查询应全表扫描。

对付未排序的表,读取少于表记录数7%的查询应该应用索引范围扫描,反之,对读取多于表记录数7%的查询应全表扫描。

注:在不合的书中,对是否应用索引的读取记录的百分比值不太同等,基础上是一个履历值,然则读取记录的百分比越低,应用索引越有效。

2. 假如列上有建索引,什么SQL查询是有用索引(INDEX)的?什么SQL查询是没有用索引(INDEX)的?

存鄙人面环境的SQL,不会用到索引:

存在数据类型隐形转换的,如:

select * from staff_member where staff_id=’123’;

列上稀有学运算的,如:

select * from staff_member where salary*2 )运算的,如:

select * from staff_member where dept_no<>2001;

应用substr字符串函数的,如:

select * from staff_member where substr(last_name,1,4)=’FRED’;

‘%’通配符在第一个字符的,如:

select * from staff_member where first_name like ‘%DON’;

字符串连接(||)的,如:

select * from staff_member where first_name||’’=’DONALD’

3. 函数的索引

日期类型也是很轻易用到的,而且在SQL语句中会应用to_char函数以查询详细的的范围日期。如:select * from staff_member where TO_CHAR(birth_day,’YYYY’)=’2003’; 我们可以建立基于函数的索引如:CREATE INDEX Ind_emp_birth ON staff_member (to_char((birth_day,’YYYY’));

二、 SQL语句排序优化

1. 排序发生的环境:

SQL中包孕group by 子句

SQL 中包孕order by 子句

SQL 中包孕 distinct 子句

SQL 中包孕 minus 或 union操作

创建索引时

2. 排序在内存照样在磁盘中进行?

在内存履行的排序速率要比在磁盘履行的排序速率快14000倍。假如是专用连接,排序内存根据INIT.ORA的sort_area_size进行分配,假如是多线程办事连接,排序内存根据large_pool_size进行分配。

sort_area_size的增大年夜可以削减磁盘排序,然则过大年夜将使ORACLE机能低落,由于所用的连接回话都邑分配到一个sort_area_size大年夜小的内存,以是,为了前进有限的查询速率,可能会挥霍大年夜量的内存。增添sort_multiblock_read_count的值使每次读取更多的内容,削减运行次数,前进机能。

三、SQL子查询的调剂

1、理解关联子查询和非关联子查询。

下面是一个非关联子查询:

select staff_name from staff_member where staff_id

in (select staff_id from staff_func);

而下面是一个关联子查询:

select staff_name from staff_member where staff_id in (select staff_id from staff_func where staff_member.staff_id=staff_func.staff_id);

以上返回的结果集是相同的,可是它们的履行开销是不合的:

非关联查询的开销——非关联查询时子查询只会履行一次,而且结果是排序好的,并保存在一个ORACLE的临时段中,此中的每一个记录在返回时都邑被父查询所引用。在子查询返回大年夜量的记录的环境下,将这些结果集排序,以及将临时数据段进行排序会增添大年夜量的系统开销。

关联查询的开销——对返回到父查询的的记录来说,子查询会每行履行一次。是以,我们必须包管任何可能的时刻子查询用到索引。

PCTUSED存储参数

PCTUSED存储参数奉告ORACLE什么时刻将曩昔满的数据块加到余暇列表中。当记录从数据表中删除时,数据库的数据块就有空间吸收新的记录,但只有当添补的空间降到PCTUSED值以下时,该数据块才被连接到余暇列表中,才可以往此中插入数据。PCTUSED的默认值是PCTUSED=40。

存储参数规则小结

(1)PCTUSED较高意味着相对较满的数据块会被放置到余暇列表中,从而有效的重复应用数据块的空间,但会导致I/O耗损。PCTUSED低意味着在一个数据块快空的时刻才被放置到余暇列表中,数据块一次能吸收很多的记录,是以可以削减I/O耗损,前进机能。

(2)PCTFREE的值较大年夜意味着数据块没有被使用若干就从余暇列表中断开连接,晦气于数据块的充分应用。PCTFREE过小的结果是,在更新时可能会呈现数据记录迁移(Migration)的环境。(注:数据记录迁移(Migration)是指记录在是UPDATE操作扩展了一个VARCHAR2类型的列或BLOB列后,PCTFREE参数所指定的空间不敷扩展,从而记录被ORACLE强制迁移到新的数据块,发生这种环境将较严重的影响ORACLE的机能,呈现更新迟钝)。

(3)在批量的插入、删除或者更新操作之前,先删除该表上的索引,在操作完毕之后在从新建立,这样有助于前进批量操作的整体速率,并且包管B树索引在操作之后有优越的机能。

3、 同优化器下的调剂;

基于资源优化器(CBO):

(1)ORACLE 8i 以上版本更多地应用资源优化器,由于它加倍智能;

(2)经由过程optimizer_mode=all_rows 或 first_rows来选择CBO;经由过程alter session set optimizer_goal=all_rows 或 first_rows来选择CBO;经由过程添加hint来选择CBO;

(3)应用基于资源优化的一个关键是:存在表和索引的统计资料。经由过程analyze table 得到表的统计资料;经由过程analyze index得到索引的统计资料。

您可能还会对下面的文章感兴趣: