SQL编写及其优化
1. 数据库查询操作的内部处理过程
1. 数据库查询操作的内部处理过程
1.1. 数据库的数据读取是以块为单位的
Oracle读取表中的数据时,是以整个块为单位的,有可能一次读多个块;从索引中得到rowid的物理位置时,也要把含rowid这个位置的块从磁盘中读出,然后才处理个别行;
1.2. 查询操作内部过程以及索引的作用
举例:select * from personal_function where employee_code= -200 ;
上述查询,如果employee_code上没有索引,则会把personal_function表数据的块全部读入内存中,同时从第一条记录查到最后一条记录,对符合条件的记录返回给用户;
如果employee_code有索引,则使用索引检索出含符合条件的Rowid的块读入内存,然后定位到rowid指示的位置上把记录返回给用户;
1.3. 执行计划概念
2.2节中,如果employee_code=-200的记录数在占总记录数超过4%,则有可能就不会用索引查找,而是直接全表扫描,这是oracle的优化器经过各种检测后会自动选择的;
Oracle对已存在数据统计特征会选择不同的执行路径(或者全表,或者使用索引等),这就产生了不同的执行计划,使能达到最大的性能。
执行计划选择的模式有RBO和CBO方式,采用CBO方式时(这是oracle公司强烈建议使用的),sql语句中from后表的先后顺序以及where条件中各个条件的先后顺序变得不是很重要了,如果RBO方式则不然;
CBO全称 Cost-based Optimizer,基于代价的优化。2.2节提到的SQL语句,Oracle是否使用索引,其内部会做各种比较,然后自动做出选择;为了使Oracle做出更精确的比较,我们应该周期性地对表进行统计,使 Oracle了解到真实情况后做出更准确的判断。因为要统计,所以称之为基于代价;
RBO全称Rule-based Optimizer,基于规则,就是说Oracle定义的一套执行先后顺序,如,有索引则一定会用索引,就如2.2节的SQL语句,但这样有时并不是最好的执行选择。
1.4. 排序处理过程以及各种引起排序的操作
举例:select * from personal_function where employee_code= -200 order by func_name;
由2.2节可知,如果没有order by语句时,oracle只要检索到一条符合条件的记录就立刻返回给用户,直到所有数据返回完毕。当有order by时,情况就不一样了,oracle会把检索到的每一条记录先保存在一个用于排序的内存中,当所有符合条件的记录在那个区域完成排序后,再返回给用户;
通过排序这个操作,oracle中间多处理了一个步骤。数据量越大,排序时间则更长,当数据量达到所找的内存区域无法容纳时,将使用磁盘做为临时排序区,此时,性能会大大降低,用户将等待更长的时间才能得到返回的结果;
因此,在一个SQL语句中,如果对返回的记录集没有顺序要求时,应该去除引起排序的语句;
引起排序的操作有:order by,distinct,union,group by
1.5. 多表join操作的内部过程
举例说明:
Esm系统中的3张表结构如下:
Employee:
EMPLOYEE_CODE |
职员代码 |
EMPLOYEE_NAME |
职员名称 |
EMPLOYEE_KANA |
职员全称 |
Emp_detial
EMPLOYEE_CODE |
职员代码 |
DEPART_CODE |
职员部门代码 |
… |
… |
Depart
Depart_CODE |
部门代码 |
DEPART_NAME |
部门名称 |
… |
… |
现在要求列出所有职员的名称和其对应的部门名称,SQL语句如下:
select aa.employee_name,cc.depart_name
from employee aa,emp_detail bb,depart cc
where aa.employee_code=bb.employee_code and bb.depart_code=cc.depart_code;
1) 读取employee的第一条记录,得到职员代码A;
2) 再在emp_detail查找职员代码为A的第一条记录,得到部门代码B;
3) 在表depart中查找部门代码为B的记录;
4) 在各个表的记录中中取出需要的信息返回给用户;
5) 。。。2步和1步是个循环操作,2步嵌套于1步中,直到所有信息返回给用户;
Oracle如果有其他的执行记录更好的话,会选择其他的;
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8135069/viewspace-414917/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/8135069/viewspace-414917/