sql优化

来源:互联网 发布:淘宝 黑搜与白搜 编辑:程序博客网 时间:2024/05/22 18:24

一、访问table的方式

        oracle采用两种访问表中记录的方式:

        (1)全表扫描

                  全表扫描就是顺序地访问表中的每条记录,oracle采用一次读入多个数据库块(database block)的方式优化全表扫描。

        (2)通过rowid访问表

         你可以采用基于rowid的访问方式情况,提高访问表的效率,rowid包含了表中记录的物理位置信息,oracle采用索引(index)实现了数据和存放数据的物理位置(rowid)之间的联系,通常索引提供了快速访问rowid的方法,因此那些基于索引列的查询就可以得到性能上的提高。

二、共享sql语句

        为了不重复解析相同的sql语句,在第一次解析之后,oracle将sql语句存放在内存中,这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享,因此,当你执行一个sql语句(有时被称为一个游标)时,如果它和之前执行过的语句完全相同,oracle就能很快获得已经被解析的语句以及最好的执行路径,oracle的这个功能大大地提高了sql的执行性能并节省了内存的使用,可惜的是oracle只对简单的表提供高速缓冲(cache buffering),这个功能并不适用于多表连接查询。

        数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了。当你向oracle提交一个sql语句,oracle会首先在这块内存中查找相同的语句,这里需要注明的是,oracle对两者采取的是一种严格匹配,要达成共享,sql语句必须完全相同(包括空格、换行等)。

        共享的语句必须满足三个条件:

        (1)字符级的比较。

        (2)两个语句所指的对象必须完全相同。

        (3)两个sql语句中必须使用相同的名字的绑定变量(bind variables)

三、选择最有效率的表名顺序(只在基于规则的优化器中有效)

        oracle的解析器是按照从右到左的顺序处理from子句中的表名,因此from子句中写在最后的表(基础表 driving table)将被最先处理,在from子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表,当oracle处理多个表时,会运用排序及合并的方式连接它们,首先,扫描第一个表(from子句中最后的那个表)并对记录进行排序,然后扫描第二个表(from子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并。

         例如:

                  表 table1 100000 条记录

                  表 table2  10条记录

                  选择table2作为基础表(最好的方法)

          如果有3个以上的表连接查询,那就需要选择交叉表 (intersection table) 作为基础表,交叉表是指那个被其他表所引用的表。

四、where子句中的连接顺序

        oracle采用自下而上的顺序解析where子句,根据这个原理,表之间的连接必须写在其他where条件之前,那些可以过滤掉最大数量记录的条件必须写在where子句的末尾。

五、select子句中避免使用“*”

        当你想在select子句中列出所有的column时,使用动态sql列引用“*”是一个方便的方法,不幸的是,这是一个非常低效的方法。实际上,oracle在解析的过程中,会将“*”依次转换成所有的列明,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。

有时间了再继续。。。