高性能编程之高效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语句,在第一次解析之后, ORACLE将SQL语句存放在内存中.这块位于系统全局区域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),就不能不说一下Oracle对sql的处理过程。当发出一条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算法来取得该sql的hash值,然后在library cache里查找是否存在该hash值;假设存在,则将此sql与cache中的进行比较;假设“相同”,就将利用已有的解析树与执行计划,而省略了优化器的相关工作。这也就是软解析的过程。
诚然,如果上面的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 初始化参数必须足够的大,如果是9i,Oracle建议使用SQL工作区自动管理,设置WORKAREA_SIZE_POLICY 为AUTO,然后调整PGA_AGGREGATE_TARGET 即可。
排序合并连接:通常情况下散列连接的效果都比排序合并连接要好,然而如果行源已经被排过序,在执行排序合并连接时不需要再排序了,这时排序合并连接的性能会优于散列连接。可以使用USE_MERGE(table_name1 table_name2)来强制使用排序合并连接。
相关推荐
这本书旨在帮助读者掌握SQL Server的高级编程技巧和管理方法,以优化数据库性能、提高数据安全性和实现高效的数据存储与检索。 1. **SQL Server架构与组件** SQL Server由多个组件构成,包括数据库引擎、Analysis ...
学习SQL Server高级查询与T-SQL编程,意味着深入理解数据库设计原理,掌握高效的数据操作和查询技巧,这在开发和管理大型数据库系统时至关重要。通过实践和熟悉这些概念,可以提高数据库性能,确保数据的准确性和...
在"Python高性能编程"这个主题中,我们关注的是如何利用Python的特性来实现高效的代码执行,优化算法,以及如何处理大数据量的情况。这通常涉及到对Python语言深入理解、内存管理、并发编程、数据结构优化等多个方面...
Oracle数据库是世界上最广泛使用的数据库系统之一,它提供了强大的功能和高效的性能,使得SQL在Oracle环境下的应用变得更为复杂和多样化。本节将详细探讨Oracle SQL的高级特性、优化技巧以及最佳实践。 一、子查询...
《Python高性能编程技术》这本书是Python开发者提升技能的宝贵资源,它深入探讨了如何利用Python的强大功能实现高效、优化的代码执行。以下是一些关键的知识点: 1. **Python解释器与性能**: Python是一种解释型...
本书旨在深入探讨如何利用Linux系统实现高性能的服务器应用,覆盖了网络协议、服务器编程的核心技术和工具框架等多个关键领域,对于想要在Linux环境下构建高效稳定服务的开发者来说,是一本不可或缺的参考书。...
SQL,即结构化查询语言,是与关系型数据库交互的基础工具,其高级编程技巧对于提升数据处理效率和数据库性能至关重要。 1. **Oracle数据库架构**:Oracle数据库由多个组件构成,包括实例(内存结构和后台进程)和...
《SQL Server 2005 高性能编程》是一本全面介绍如何在 SQL Server 2005 上构建高度可用和高效系统的重要参考书籍。它不仅涵盖了理论知识,还提供了实用的技术细节和最佳实践建议,对于希望深入了解 SQL Server 2005 ...
Oracle SQL是数据库管理员和开发人员在管理Oracle数据库时...总之,"Oracle SQL 高级编程"涵盖了数据库管理和开发的多个方面,通过学习和实践,你将能够编写出更高效、更灵活的SQL查询,更好地管理和维护Oracle数据库。
在Linux平台上进行高性能服务器编程是IT领域中的一个重要课题,它涉及到网络编程、多线程、内存管理、I/O模型优化等多个方面。C/C++作为底层系统编程的主要语言,提供了高效且灵活的编程能力,使得开发者能够更深入...
《Oracle SQL 高级编程》一书的随书脚本集合是学习和深入理解Oracle数据库管理及SQL高级特性的宝贵资源。这些脚本涵盖了从基础查询到复杂的数据操作、存储过程、函数以及触发器等多个方面,旨在帮助读者提升在Oracle...
《SQLServer2000高级编程技术》这本书深入探讨了SQL Server 2000这一经典数据库管理系统中的高级编程技术。SQL Server 2000是微软公司推出的数据库平台,虽然现在已经有一些老旧,但其在许多企业中仍然占据着重要的...
本书涵盖了SQL的高级概念和技术,帮助读者深入理解如何利用SQL进行复杂的数据操作、优化查询性能以及设计高效的数据存储方案。 SQL(Structured Query Language,结构化查询语言)是用于管理关系型数据库的标准语言...
它全面覆盖了Oracle SQL的各种高级特性,提供了独到的见解和详实的实例,旨在帮助读者在实际工作中更加高效地管理和优化数据库。 1. **子查询**:Oracle SQL中的子查询是SQL查询语句中嵌套的另一个查询,用于在主...
Oracle SQL高级编程通常指的是使用SQL语言实现复杂的数据操作、查询优化、性能调整和事务管理等方面的高级技术。 以下是Oracle SQL高级编程中的一些重要知识点: 1. 数据操纵语言(DML):在Oracle SQL中,可以...
《SQL Server 2000设计与T-SQL编程》这本书是针对数据库管理和开发人员的一份宝贵资源,尤其对于那些正在学习或...通过学习本书,你将具备设计高效数据库、编写高性能T-SQL代码的能力,为你的职业生涯增添宝贵的技能。
1. **数据库设计**:良好的数据库设计是高效SQL编程的前提。这包括对实体关系模型(ER模型)的理解,使用范式理论(如第一范式、第二范式、第三范式等)来减少数据冗余,以及如何创建和管理表、索引、主键和外键。 ...
在IT行业中,数据库编程是至关重要的技能之一,尤其是在C++这样的强类型系统语言与SQL Server 2005这样的关系型数据库管理系统结合时。本文将深入探讨如何在C++环境中利用SQL Server 2005进行数据库操作。 首先,...
在SQL Server数据库高级编程中,我们经常会涉及到三个关键概念:触发器、存储过程和自定义函数。这些元素是数据库系统中的重要组成部分,用于实现复杂的业务逻辑和数据管理。以下是对这三个概念的详细解释: 1. **...