SQL语句优化方法分析与探讨

来源 :电脑知识与技术 | 被引量 : 0次 | 上传用户:jematrix
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:随着数据库应用系统中数据的增加,系统的响应速度成为系统设计中需要解决的主要问题。由于用户对数据库的要求越来越高,因此必须对数据库进行优化。系统优化的一个很重要的方面就是SQL语句本身的优化,文章从应用的角度论述了SQL语句优化的一些方法。
  关键词:数据库;优化;SQL
  中图分类号:TP311文献标识码:A文章编号:1009-3044(2007)15-30611-03
  Analysis and Discussion of SQL Statement Optimization
  LIU Ming-hua1,2, ZHOU Li1
  (1. Glorious Sun School of Business and Management, Donghua University, Shanghai 200051, China;2. Information Center, Fujian Polytechnic of Information Technology, Fuzhou 350003, China)
  Abstract:In database application systems, performance becomes one of their main problems needed to be resolved with the increase of data in it. For the demands that the customer wants the database are more and more effective, and this makes us optimize the design of the database. SQL optimization is a very important aspect in system optimization. This paper states some methods of SQL optimization from the application.
  Key words:database;optimization;SQL
  
  1 引言
  
  在应用系统开发过程中,由于数据库数据的逐渐增加,系统的响应速度就成为系统设计中越来越需要解决的问题。数据库管理系统设计优化一个很重要的方面就是SQL语句的优化。对于数据库应用程序来说,重点在于SQL的执行效率,本文从SQL语言的定位、分析、调整、优化和技巧五个方面分别讨论SQL语句优化的一些具体方法。
  
  2 SQL语句优化方法
  
  2.1 SQL编码的定位
  首先是查找大量使用内存及磁盘I/O的语句,并对其进行准确定位。例如:
  selectdisk_reads,sql_text
  fromv$sqlarea
  where disk_reads>20000
  order bydisk_reads desc;
  Disk_read SQL_TEXT
  12,987select order#,columns,types from orders
  Where substr(ordered,1,2)=:1
  11,231select custid,city from customers
  Where city=CHICAGO
  然后查找逻辑读最多的查询语句还有查找锁死其他用户操作的用户。例如:
  Select a.serial#, a, sid, s.username, b.id1, c.sql_text
  Form v$session a,v$lock b,v$ sqltext c
  Where b.id1 in
  (select distinct e.id1
  From v$session d,v$lock e
  Where d.lockwait=e.kaddr)
  and a. Sid=b.sid
  and c.hash_value=a.sql_hash_value
  And b.request=0;
  2.2 SQL编码分析
  SQL语句的分析过程(无论是否使用优化器,分析过程都相同),包括以下几方面:
  –检查语法
  –搜索共享池
  –搜索数据字典
  –计算搜索路径
  为提高SQL的共享性,建议使用统一的SQL编程标准如下:
  –Put all verbs in one case
  –Begin all SQL verbs on a new line
  –Right or left align verbs with the initial verb
  –Bind variables will ensure all SQL is equal so statements is not reparsed
  2.3 SQL编码调整
  使用下列信息确定访问路径:
  –SQL语句
  –在引用表上的索引
  –执行计划
  –当前优化模式
  –提示变量
  –表统计(如果是基于成本的优化,可知道选择何种优化)
  2.4 SQL编码的具体优化
  2.4.1 优化器
  以Oracle为例,Oracle的优化器有三种:
  –基于规则的优化(RULE)
  –基于成本的优化(COST)
  –基于选择性的优化(CHOOSE)
  以下分别提出三种优化的方法。首先讨论基于规则的优化(rules),Oracle分析器从右到左处理,最后一个表最先被处理。最后一个表应该是包含父键或连接判定到其它表,SQL每一条件都被分级。如此类推,如果优化器有多个索引可选,唯一索引总排在非唯一索引的前面。若两个索引一样,如果是不同表上的两个索引,表的顺序将用于决定使用那个索引;如果两个索引在同一表上,首先引用的索引将被使用。除索引以外,WHERE子句中比较常量和变量比字段之间的比较优先。
  然后是基于成本的优化(COST),基于成本的优化器没有固定的费用评估规则,评估是灵活的并基于分析统计的结果变化,逻辑读取的评估标准。用最少的资源实现最大吞吐量(ALL_ROWS)。用最少的资源实现首行最佳响应时间(FIRST_ROWS)。100%地选择唯一索引;计算非唯一索引的选择性;用列的最大最小值处理评估范围;Hint可被用于影响优化器。另外可以通过加入hint来强制改变优化策略。
  FULL——强制进行全表扫描
  SELECT /*+ FULL(table_name)*/ column1,column2…
  INDEX——强制使用指定的索引
  SELECT /*+ INDEX(table_name index_name1, index_name2…)*/
  ORDERED——强制指定查询时的驱动表
  SELECT /*+ ORDERED*/ column1,column2…FROM table1, table2
  ALL_ROWS——基于成本的优化,最大的提高数据的吞吐性
  SELECT /*+ ALL_ROWS */ (ALL_ROWS hint通常会禁用索引)
  最后说明基于选择性的优化(CHOOSE)。From子句的内表外表次序:在表的连接中一个表作为外表,也称驱动表,另一个表作为内表。首先检查外表的每一行是否满足查询条件,对于满足条件的那些外表记录,扫描每一个内表记录并且与它在连接列上进行匹配。优化器选择外表的根据是:满足条件的返回数据行数少;或定位数据行时需要读操作的次数多(不能有效利用索引);如果有三个或以上的表进行关联查询,中间的表应该作为外表,与之相反的表作为内表。以下是确定表连接次序的实例(基于Sybase):
  select TableA.colx, TableB.coly from TableA, TableB where TableA.col1 = TableB.col1 and TableB.col2=anything and TableA.col2 = something
  假设A,B表都是有10条记录满足条件
  表A:1,000,000条记录,每个数据页上10行记录,(共100,000页),没有索引。(定位数据行时需要读操作的次数多-应选作外表)
  表B:100,000条记录,每个数据页上10行记录,(共10,000页),在连接列上有聚簇索引,索引树为3层。
  通过以下的计算说明应该选表A为外表。如果表A是外表:对它的存取是通过全表扫描,当找到第一个满足条件的记录,在表B上用聚簇索引查找B表中col1列与从A表检索出的值匹配的数据行,做完后继续扫描A表,重复上面的过程,直到A表全部扫描完毕。假设A表有10条满足条件的记录,则该次查询所需的读数据页的次数如下:
  - 读取的页数
  - A表扫描100,000
  - 0次B表索引扫描10*3=30
  - 合计100,030
  如果表B是外表:对它的存取是通过聚簇索引,当找到第一个满足条件的记录,在表A上用全表扫描A表中col1列与从B表检索出的值匹配的数据行,做完后继续扫描B表,重复上面的过程,直到B表全部扫描完毕。假设B表有10条满足条件的记录,则该次查询所需的读数据页的次数如下:
  - 读取的页数
  - B表扫描 3
  - 10次 A表全表扫描10*100,000=1,000,000
  - 合计1,000,003
  WHERE子句后面参数的写法:
  有索引且能用上索引的表达式,其格式有:
  <column><operator><expression>
  <expression><operator><column>
  <column> is null(对Oracle不适合)
  不等操作符!>和!=是特殊情况,这时查询优化器不能使用索引来定位搜索。
  下面的例子是可优化的:
  au_lname = "Bennett"
  price >= $12.00
  price >= $12.00*3
  advance >10000 and advance < 20000
  下面的例子则不是:salary=commission /*两边都是列名*/
  substring(lname,1,3) ="Ben" /*列名边不允许函数*/
  advance * 2 = 5000 /*列名边不允许表达式*/
  advance =$10000 or price = $12.00 /*含有or谓词*/
  2.4.2 可以转化为优化的查询条件书写
  (1)between谓词可以转化为>=and<=子句,比如:
  price between 10 and 20可以转化为 price>= 10 and <=20
  (2)like子句中匹配值的第一个字符是常量,也可以进行转换,例如:
  like "sm%"可以转换成 >="sm" and <"sn"
  表titles和表titleauthor是一对多关系,title_id在表titles中是唯一的。
  1.select au_lname,title from titles t,titleauthor ta,authors a where t.title_id =ta.tatle_id and a.au_id=ta.au_id and t.title_id ="T81002"title_id在表titles中是唯一的。
  2.select au_lname,title from titles t,titleauthor ta,authors a where t.title_id =ta.tatle_id and a.au_id=ta.au_idand ta.title_id="T81002"这是最差的,因为title_id在表titleauthor中非唯一。
  3.select au_lname,title from titles t,titleauthor ta,authors a where t.title_id =ta.tatle_id and a.au_id=ta.au_id and t.title_id="T81002"and ta.title_id= "T81002"这是最优的。
  查询1就可能比查询2执行的好,因为title_id是唯一的,筛选的效果会好些,第3个查询提供了两个表的搜索变量,给优化器更多的选择来调整连接操作表的顺序。
  2.4.3 连接顺序(只适用于基于规划的优化器)
  Oracel采用自下而上的顺序解析WHERE子句,可以过滤掉最大数量记录的条件写在WHERE子句的末尾。
  SELECT ***
  FROM EMP E
  WHERE 30 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO)
  AND SAL > 30000
  AND JOB= 'MANAGER'
  2.4.4 查询条件书写的注意事项
  编写SQL语句时关于查询条件书写应注意在搜索子句的列名边要避免函数、算术操作符和其它的表达式避免不兼容的数据类型使用复合索引的第一个列名给优化器提供尽可能多的查询条件-可以用上索引的检索条件。
  2.5 编码的技巧
  2.5.1 or与in子句的优化
  查询优化器对and和or子句的查询采用不同的处理方式,包含or或in子句查询的优化依赖于在这些子句中使用的表上的索引和这些子句是否返回重复的结果。or子句通常采用下面的形式:
  where column1 = or column1=
  where column1 = or column2=
  如果or子句中使用的列上有任一个列没有索引或使用索引的开销超过了全表扫描的开销,则执行全表扫描。
  OR策略:使用or子句的查询相当于多个查询的union,一些记录可能满足多个条件,但只应当返回一次。OR策略将使用每一列的索引把满足每个or子句的记录行merge 到一起,然后再去掉重复数据行。如果or子句不会返回重复记录,优化器就会使用多个匹配索引查询,每个or子句单独考虑,可以使用不同的索引。如or子句返回重复记录,则采用比较费时的or策略。先把满足每一个or子句的记录行的ID号存储到数据库tempdb中的工作表中,然后进行排序并删除重复的ID号,再利用行ID从基表中检索出不 重复的数据行。or策略在被访问的数据页上维护一共享锁所以会影响并发性。在使用隔离级别3或holdlock子句的情况下,要避免or查询。当在索引列上进行条件判断时,用>=替代>例如下面的查询,在int_col上建有索引:
  select * from table where int_col > 3
  该查询使用索引找到第一个int_col=3的值,然后向前扫描。如果表中有许多行中int_col的值是3,则该查询不得不扫描许多页后找到第一个int_col大于3的数据行。
  若把查询写成下面的形式,则会更有效:
  select * from table where int_col >= 4 exist和 not exist 在子查询,exists和in要比not exists和not in执行得快,因为对于exists和in,优化器只要找到一条记录就可以返回TRUE,而对于not exists和not in则必须检查所有的值。
  2.6 SQL编码的开发调优
  SQL编码的开发调优一般应该考虑以下一些原则:
  1、在搜索子句的列名边要避免函数、算术操作符和其它的表达式,除非建立基于函数的索引;
  2、使用复合索引的第一个列名;
  3、SELECT子句中避免使用'*';
  4、用TRUNCATE替代DELETE;
  5、尽量多使用COMMIT;
  6、避免在索引列上使用IS NULL和IS NOT NULL(Oracle);
  7、用UNION-ALL 替换UNION(如果有可能的话);
  8、使用较大的BUFFER(比如10MB, 10,240,000)可以提高EXPORT和IMPORT的速度;
  9、在物理存储上分离表和索引;
  10、当连接的两个或多个数据表的数据量都过大时,考虑将数据表进行整合到一张表中;
  11、对于批处理的操作,使用指定的大的回滚段;
  12、当使用存储过程处理数据量比较大表时,可考虑使用中间表或临时工作表;
  13、当没有可用的索引时,则只能创建工作表对结果数据排序;
  14、将纵向表拆成横向表处理,比如费用字段拆成市话、长话、IP费用等;
  15、将层次结构复杂(如雪花形结构)的维表如咨询树类型,或将信息比较多的维表比如客户信息表,直接取出维度信息放进事实表中,并对该表建立索引,增加查询的速度。
  2.7 SQL编码的应用调优
  SQL编码的应用调优应该注意以下几点:
  1、对于频繁进行更新和插入的表,比如状态监控表和日志表使用行级锁;
  2、对于频繁进行更新和插入的大数据量表,比如日志表,要考虑所建索引的数量,避免建过多的索引(会降低插入和更新操作的执行效率,并且占用大量的存储空间,可能比原表还大);
  3、对于字段较多并且包含memo,text,image等记录长度大的数据表,在查询时要考虑执行效率,比如对于批量工单查询,只需返回有限的几个字段(减少I/O和执行时间),对于工单的精确查询返回全部字段的值;
  4、在应用中对业务的处理引入事务机制和异常处理机制,保证业务处理的完整性;
  5、考虑主外键约束的使用(灵活与严整),使用触发器或事务处理的方式来保证参照完整性;
  6、对于数据量不大的表,可以将数据一次取到内存中,然后再进行计算和查找,比如树形结构的展现。
  
  3 总结
  
  SQL的性能优化是一个复杂的过程,涉及数据库层的资源配置、网络层的流量控制以及操作系统层的总体设计。不同的数据库都有各自不同的功能和特色,在实际应用环境中,应该根据实际情况选择较合理的数据库系统设计和优化策略,这样才能充分利用数据库管理系统提供的高性能服务使应用系统能充分发挥其高效的功能。
  
  参考文献:
  [1] 袁鹏飞. SQL Server7.0 数据库系统管理与应用开发[M]. 北京:人民邮电出版社,1999.
  [2] Patrick O Neil, Elizabeth Oneil. DATABASE: Principles, Programming and Performance[M]. Beijing: Higher Education Press, Morgan Kaufmann Publishers, 2001.
  [3] 微软公司. Microsoft SQL Server 7.0系统管理[M].北京:北京希望电子出版社,1999.
  [4] SQL Server数据库性能优化技术[M]. 中国IT认证实验室(China IT Lab).
  [5] 吕映芝, 张素芝, 蒋维杜. 编译原理[M]. 北京:高等教育出版社,2000.12.
  注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
其他文献
摘要:本文主要介绍了基于DVD系统将CD格式文件压缩为MP3文件存储到U盘的方法和基本原理,充分利用DVD系统自身的播放功能获取CD上的PCM数字信息,经过硬件解码,压缩成MP3格式,通过文件系统的操作经USB传输将数据写入U盘。  关键词:DVD系统;FAT文件系统;CD_RIPPING  中图分类号:TP37文献标识码:A文章编号:1009-3044(2007)16-31135-01  Fil
期刊
摘要:P2P网络技术在使人们享受信息资源,增强网络可用性的同时,也带来了新的网络安全问题。本文对P2P网络的安全性进行了分析,并提出了相应对策。  关键词:P2P;网络安全;网络技术  中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)15-30653-01  Analyses and Countermeasures of P2P Network Security  MA
期刊
摘要:文章以Visual FoxPro 6.0数据库管理系统为软件平台,通过查询实例阐述结构化查询语言(Structured Query Language,简称SQL)如何反映关系数据库三级模式结构,如何体现关系代数和关系演算思想。  关键词:关系数据库三级模式结构;关系代数;关系演算;SQL   中图分类号:TP311文献标识码:A 文章编号:1009-3044(2007)15-30606-03
期刊
摘要:本文主要描述了中国铁路通信系统的几十年来的发展历史,并通过对GSM-R系统具体原理和即将投入运营的合宁高速铁路GSM-R系统的具体应用的介绍,充分说明了GSM-R系统是铁路未来通信发展的方向,是铁路跨越式发展,全面实现信息化建设的里程碑。  关键词:铁路通信系统;GSM-R;信息化;网络建设;业务功能;历史意义  中图分类号:TE46文献标识码:A文章编号:1009-3044(2007)15
期刊
摘要:为了更好地、灵活的开发数据库应用软件,我们需要深入的研究ADO.NET的数据库访问机制,理解ADO.NET数据库的连接方法、对数据的操作与访问。ADO.NET添加了许多新的对象,如Dataset、DataReader、DataAdapter等,使得对数据库的操作更加简单。本文通过对ADO.NET数据交换原理、数据访问对象模型的使用,介绍了使用ADO.NET方法的数据库访问技术。  关键词:A
期刊
摘要: ASP. NET作为微软的.NET构架中的一部分,业已成为开发新型电子商务系统安全解决方案的主流开发工具。主要讨论了与ASP相比,ASP.NET的优势,注入式攻击问题以及实现 ASP. NET应用程序级别安全性的策略和解决方案。  关键词:.NET;ASP;安全;注入式攻击  中图分类号: TP393文献标识码: A文章编号:1009-3044(2007)15-30676-03  The
期刊
摘要:随着企业网、校园网及宽带网的迅速发展,基于三层交换与路由技术的交换机的应用已从最初网络中心骨干层、汇聚层渗透到接入层。本文对三层交换和路由技术、VLAN技术的应用进行了全面介绍,并对基于CISCO交换机的局域网VLAN配量进行了详尽描述。  关键词:VLAN;第三层交换;路由器;交换技术  中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)15-30657-03  
期刊
摘要:中国加入WTO以后,烟草工业企业面对市场的压力越来越大,推进服务营销尤为重要。然而,在Internet时代客户比以前有了更多的选择,而且只需轻轻点击鼠标就可以贴近你或离你而去。因此,对于企业来说仅仅满足客户的需求已远远不够,更重要的是如何能让服务给客户留下深刻的印象。CSS作为一种前景广阔的企业解决方案,也越来越多地显示出其在以客户服务为中心的时代无可替代的重要地位。  关键词:烟草行业;.
期刊
摘要:TCP/IP协议现在用得非常广泛,但它本身也有一些安全上的缺陷。描述了各种各样针对这些缺陷的攻击,包括序列号攻击,SYN Flood攻击。提出了一些对这些攻击的防御方法。  关键词:TCP协议;网络安全;协议攻击;安全防御  中图分类号:TP393 文献标识码: A 文章编号:1009-3044(2007)15-30682-01  Security Problems Study in the
期刊
摘要:通过叙述ASP连接Access或Sql Server数据库的几种方式,来分析访问Access和SQL Server两种Web数据库的安全机制。  关键词:ASP;Web数据库;安全机制  中图分类号:TP309文献标识码:A文章编号:1009-3044(2007)15-30621-01  Safety Mechanism of Web Database Based on ASP  XU We
期刊