高性能编程之高效SQL(1)

高性能编程之高效SQL

SQL 语言是一种强大而且灵活的语言。SQL的广泛适用性,以至于搞财务的MM都能写一个简单的查询用户资料的SQL语句。

但不同的用户可以写出很多不同的 SQL 语句来获取相同的结果。亦即:语法 (syntactical) 不同的 SQL 语句,有可能在语义 (semantical) 上是完全相同的。但是尽管这些 SQL 语句最后都能返回同样的查询结果,它们在 DB2 中执行所需要的时间却有天壤之别!

因此,可以说“能写并不代表会写”!满足功能需求是较低要求,效率高才是王道!

 

在介绍优化的方法前,先简要介绍下一些预备知识。

 

1. ORACLE优化器

    ORACLE的优化器共有3:

   a.  RULE (基于规则)   b. COST (基于成本)  c. CHOOSE (选择性)

    设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖.

   为了使用基于成本的优化器(CBO, Cost-Based Optimizer) , 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性.

如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关. 如果table已经被analyze, 优化器模式将自动成为CBO , 反之,数据库将采用RULE形式的优化器.

   在缺省情况下,ORACLE采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器.

 

2.     访问Table的方式

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

 a.     全表扫描

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

b.     通过ROWID访问表

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

 

 3.    共享SQL语句

为了不重复解析相同的SQL语句,在第一次解析之后, ORACLESQL语句存放在内存中.这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享. 因此,当你执行一个SQL语句(有时被称为一个游标),如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的执行路径. ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用.

     可惜的是ORACLE只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适用于多表连接查询.数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了.当向ORACLE 提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句.这里需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须完全相同(包括空格,换行等).

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

 A.      字符级的比较:

当前被执行的语句和共享池中的语句必须完全相同.

B.      两个语句所指的对象必须完全相同:

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

说明:所谓绑定变量,就是给变量赋值。

 

4. Oracle的硬解析和软解析

提到软解析(soft prase)和硬解析(hard prase),就不能不说一下Oraclesql的处理过程。当发出一条sql语句交付Oracle,在执行和获取结果前,Oracle对此sql将进行几个步骤的处理过程:
1
、语法检查(syntax check)
检查此sql的拼写是否语法。
2
、语义检查(semantic check)
诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。
3
、对sql语句进行解析(parse)
利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)
4
、执行sql,返回结果(execute and return)

其中,软、硬解析就发生在第三个过程里。

Oracle利用内部的hash算法来取得该sqlhash值,然后在library cache里查找是否存在该hash值;假设存在,则将此sqlcache中的进行比较;假设“相同”,就将利用已有的解析树与执行计划,而省略了优化器的相关工作。这也就是软解析的过程。
   
诚然,如果上面的2个假设中任有一个不成立,那么优化器都将进行创建解析树、生成执行计划的动作。这个过程就叫硬解析。

创建解析树、生成执行计划对于sql的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。
   
这就是在很多项目中,倡导开发设计人员对功能相同的代码要努力保持代码的一致性,以及要在程序中多使用绑定变量的原因。

 

5. 表的三种基本连接方式

NESTED LOOP:对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择。在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大(大于1 万不适合),要把返回子集较小表的作为外表(CBO 默认外表是驱动表),而且在内表的连接字段上一定要有索引。当然也可以用ORDERED 提示来改变CBO默认的驱动表,使用USE_NL(table_name1 table_name2)可是强制CBO 执行嵌套循环连接。

 

 

HASH JOIN :散列连接是CBO 做大数据集连接时的常用方式,优化器使用两个表中较小的表(或数据源)利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配的行。
   
这种方式适用于较小的表完全可以放于内存中的情况,这样总成本就是访问两个表的成本之和。但是在表很大的情况下并不能完全放入内存,这时优化器会将它分割成若干不同的分区,不能放入内存的部分就把该分区写入磁盘的临时段,此时要有较大的临时段从而尽量提高I/O 的性能。也可以用USE_HASH(table_name1 table_name2)提示来强制使用散列连接。如果使用散列连接HASH_AREA_SIZE 初始化参数必须足够的大,如果是9iOracle建议使用SQL工作区自动管理,设置WORKAREA_SIZE_POLICY AUTO,然后调整PGA_AGGREGATE_TARGET 即可。

 

排序合并连接:通常情况下散列连接的效果都比排序合并连接要好,然而如果行源已经被排过序,在执行排序合并连接时不需要再排序了,这时排序合并连接的性能会优于散列连接。可以使用USE_MERGE(table_name1 table_name2)来强制使用排序合并连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL技术内幕是一本深入探讨MySQL数据库内部机制的书籍。它通过详细介绍MySQL存储引擎、查询优化器、事务处理等核心组件,帮助开发者理解MySQL的工作原理和优化技巧。 MySQL作为最流行的开源关系型数据库之一,拥有广泛的应用领域,包括Web应用、大数据、云计算等。掌握MySQL的技术内幕对于开发者来说是非常重要的,可以帮助他们更好地设计和优化数据库。 SQL编程是MySQL数据库开发中的关键部分。SQL(Structured Query Language)是一种被广泛应用于关系型数据库的查询语言,通过SQL语句可以对数据库进行增删改查操作。 在MySQL技术内幕中,SQL编程也占据了一章的篇幅。该章节重点介绍了SQL的基本语法、查询性能优化以及一些高级技巧和最佳实践。 首先,书中详细介绍了SQL的基本语法,包括SELECT、INSERT、UPDATE和DELETE等常用语句的使用方法和语法规则。读者可以通过学习这些基本语法,掌握SQL编程的基础知识。 其次,书中还介绍了一些SQL查询性能优化的技巧。例如,可以通过合适的索引设计、优化查询语句以及避免全表扫描等方法提升查询性能。 最后,书中还提供了一些高级的SQL编程技巧和最佳实践。例如,如何处理大数据量的查询、如何处理复杂的数据操作以及如何编写高效的存储过程等等。 通过学习MySQL技术内幕中的SQL编程部分,开发者可以更好地理解和应用SQL语言,提高数据库的性能和可维护性。掌握MySQL技术内幕中的SQL编程知识,对于提高开发效率和减少数据库性能问题是非常有帮助的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值