??xml version="1.0" encoding="utf-8" standalone="yes"?>97色伦亚洲国产,精品日韩在线一区,91精品国产自产在线http://www.aygfsteel.com/zhuzi1987/category/33216.htmlJAVA+YOU!中国的开发者们加a!!zh-cnFri, 05 Dec 2008 21:15:59 GMTFri, 05 Dec 2008 21:15:59 GMT60【{】T-SQL ~码标准--对ORACLE开发也很有启发http://www.aygfsteel.com/zhuzi1987/archive/2008/12/02/243866.html竹子竹子Tue, 02 Dec 2008 02:50:00 GMThttp://www.aygfsteel.com/zhuzi1987/archive/2008/12/02/243866.htmlhttp://www.aygfsteel.com/zhuzi1987/comments/243866.htmlhttp://www.aygfsteel.com/zhuzi1987/archive/2008/12/02/243866.html#Feedback0http://www.aygfsteel.com/zhuzi1987/comments/commentRss/243866.htmlhttp://www.aygfsteel.com/zhuzi1987/services/trackbacks/243866.htmlT-SQL ~码标准

发布日期Q?4/15/2005 | 更新日期Q?4/15/2005

Brian Walker

可能让h觉得很奇怪,但好像的没有什?/strong>正式?/strong>”T-SQL ~码标准。早?/strong> 1999 q末的时候,我惊喜地发现 John Hindmarsh 提出?/strong> SQL Server 7.0 标准Q我?/strong> 2000 q?/strong> 2 月的C论中对他的某些q行了ȝ。(2000 q?/strong> 2 月以及本月的下蝲中都包括?/strong> John 原来的标准。)后来Q?/strong>Ron Talmage 撰写了一pd专栏文章Q提Z他对各种最x?/strong>的徏议,当然Q?/strong>SQL Server 组也已正式发布?/strong> SQL Server 最x法分析器 (SQLBPA)。现在,一位具有超q?/strong> 25 q经验的数据库管理员和应用程序开发员 Brian Walker 又提Z他的和提C?/strong>

*

q行 T-SQL ~程时常怼忽略~码标准Q但q些标准却是开发小l顺利开展工作的关键工具。这里介l的~码标准是我多年的开发成果。它们当然还没有得到普遍接受Q而且不可否认Q有些标准带有主观色彩。我的目的实际上更多的是Z提高大家的意识,而不是吹捧自己是 T-SQL 样式斚w的仲裁者:最重要的是要徏立某些合理的~码标准q循这些标准。您在这文章中会发现有?T-SQL ~程的一pd不同的编码标准、技巧和提示。它们ƈ未以M特定的优先或重要性顺序列出?/p>

让我们从格式开始。表面上QT-SQL 代码的格式似乎ƈ不重要,但一致的格式可以使您的同事(不论是同一组的成员还是更大范围的 T-SQL 开发团队的成员Q更L地浏览和理解您的代码。T-SQL 语句有一个结构,遵@一目了然的l构使您可以更轻村֜查找和确认语句的不同部分。统一的格式还使您可以更轻村֜在复?T-SQL 语句中增删代码段Q调试工作变得更容易。下面是 SELECT 语句的格式示例:

       SELECT C.Name
, E.NameLast
, E.NameFirst
, E.Number
, ISNULL(I.Description,'NA') AS Description
FROM tblCompany AS C
JOIN tblEmployee AS E
ON C.CompanyID = E.CompanyID
LEFT JOIN tblCoverage AS V
ON E.EmployeeID = V.EmployeeID
LEFT JOIN tblInsurance AS I
ON V.InsuranceID = I.InsuranceID
WHERE C.Name LIKE @Name
AND V.CreateDate > CONVERT(smalldatetime,
'01/01/2000')
ORDER BY C.Name
, E.NameLast
, E.NameFirst
, E.Number
, ISNULL(I.Description,'NA')
SELECT @Retain = @@ERROR, @Rows = @@ROWCOUNT
IF @Status = 0 SET @Status = @Retain

Z个嵌套代码块中的语句使用四个I格的羃q。(上述代码中的多行 SELECT 语句是一?SQL 语句。)在同一语句中开始新行时Q SQL 关键字右寚w。将代码~辑器配|ؓ使用I格Q而不是用制表符。这P不管使用何种E序查看代码Q格式都是一致的?/p>

►大写所有的 T-SQL 关键字,包括 T-SQL 函数。变量名U及光标名称使用混和大小写。数据类型用小写?/p>

名别名要短,但意义要量明确。通常Q用大写的表名作ؓ别名Q?AS 关键字指定表或字D늚别名?/p>

►当一?T-SQL 语句中涉及到多个表时Q始l用表名别名来限定字段名。这使其他h阅读h更清楚,避免了含义模p的引用?/p>

►当相关数字出现在连l的代码行中Ӟ例如一pd SUBSTRING 函数调用Q,它们排成列。这样容易浏览数字列表?/p>

Z用一个(而不是两个)I分隔 T-SQL 代码的逻辑块,只要需要就可以使用?/p>

►声?T-SQL 局部变量(例如 @lngTableIDQ时Q用适当的数据类型声明和一致的大写?/p>

?strong>始终指定字符数据cd的长度,q确保允许用户可能需要的最大字W数Q因出最大长度的字符会丢失?/p>

?strong>始终指定十进制数据类型的_ֺ和范_否则Q将默认为未指定_ֺ和整数范围?

Z用错误处理程序,但要C行首 (BOL) 中的错误查示例不会象介绍的那栯v作用。用来检?@@ERROR pȝ函数?T-SQL 语句 (IF) 实际上在q程中清除了 @@ERROR |无法再捕获除零之外的M倹{(即ɽCZ起作用,它们也只能捕h后发生的一个错误,而不是您更想捕获的第一个错误。)必须使用 SET ?SELECT 立即捕获错误代码Q如前面CZ所C。如果状态变量仍然ؓӞ应{换到状态变量?

►避免?#8220;未声明的”功能Q例如系l表中未声明的列、T-SQL 语句中未声明的功能或者未声明的系l存储过E或扩展的存储过E?

?strong>不要依赖M隐式的数据类型{换。例如,不能为数字变量赋予字W|而假?T-SQL 会进行必要的转换。相反,在ؓ变量赋值或比较g前,应用适当?CONVERT 函数使数据类型相匚w。另一个示例:虽然 T-SQL 会在q行比较之前对字W表辑ּq行隐式且自动的 RTRIMQ但不能依赖此行为,因ؓ兼容性别设|非字符表达式会使情况复杂化?/p>

?strong>不要空的变量值直接与比较q算W(W号Q比较。如果变量可能ؓI,应?IS NULL ?IS NOT NULL q行比较Q或者?ISNULL 函数?/p>

Z要?STR 函数q行舍入Q此函数只能用于整数。如果需要十q制值的字符串Ş式,应先使用 CONVERT 函数Q{至不同的范围Q或 ROUND 函数Q然后将其{换ؓ字符丌Ӏ也可以使用 CEILING ?FLOOR 函数?/p>

Z用数学公式时要小心,因ؓ T-SQL 可能会将表达式强制理解ؓ一个不需要的数据cd。如果需要十q制l果Q应在整数常量后加点和零 (.0)?/p>

►决不要依赖 SELECT 语句会按M特定序q回行,除非?ORDER BY 子句中指定了序?/p>

►通常Q应?ORDER BY 子句?SELECT 语句一起用。可预知的顺序(即不是最方便的)比不可预知的序强,其是在开发或调试q程中。(部v到生产环境中之前Q可能需要删?ORDER BY 子句。)在返回行的顺序无关紧要的情况下,可以忽略 ORDER BY 的开销?/p>

Z要在 T-SQL 代码中用双引号。应为字W常量用单引号。如果没有必要限定对象名Uͼ可以使用Q非 ANSI SQL 标准Q括号将名称括v来?/p>

►在 SQL Server 2000 中,量使用表变量来代替临时表。如果表变量包含大量数据Q请注意索引非常有限Q只有主键烦引)?/p>

►先在例E中创徏临时表,最后再昑ּ删除临时表。将 DDL ?DML 语句混合使用有助于处理额外的重新~译zd?/p>

认识C时表q不?/strong>不可使用Q适当C用它们可以某些例程更有效,例如Q当需要重复引用大型表或常用表中的某个数据集时。但是,对于一ơ性事Ӟ最好用导?

?/em>使用表?UDF 时要心Q因为在变量Q而不是常量)中传递某个参数时Q如果在 WHERE 子句中用该参数Q会D表扫描。还要避免在一个查询中多次使用相同的表?UDF。但是,表?UDF 实h某些非常方便的动态编译功能?em>[相关资料Q参?/em> Tom Moreau ?/em> 2003 q?/em> 11 月䆾生成序列?/em>专栏中的使用 UDF 填充表变?/em>。-~者按Q?/em>

►几乎所有的存储q程都应在开始时讄 SET NOCOUNT ONQ而在l束时设|?SET NOCOUNT OFF?em>[SET NOCOUNT ON ?/em> SQL Server 无需在执行存储过E的每个语句后向客户端发?/em> DONE_IN_PROC 消息?/em>- ~者按] 此标准同样适用于触发器?/p>

►只要在例程中用多个数据库修改语句Q包括在一个@环中多次执行一个语句,应考虑声明昑ּ事务?/p>

Z用基于光标的Ҏ或时表Ҏ之前Q应先寻扑֟于集的解x案来解决问题。基于集的方法通常更有效?/p>

Z临时表一P光标q不是不可用。对型数据集?FAST_FORWARD 光标通常要优于其他逐行处理ҎQ尤其是在必d用几个表才能获得所需的数据时。在l果集中包括“合计”的例E通常要比使用光标执行的速度快。如果开发时间允许,Z光标的方法和Z集的Ҏ都可以尝试一下,看哪一U方法的效果更好?/p>

Z用包含序P?1 ?NQ的表很方便?/p>

►理?CROSS JOIN 的工作原理ƈ加以利用。例如,您可以在工作数据表和序号表之间有效地使用 CROSS JOINQ结果集中将包含每个工作数据与序L合的记录?

►我的结束语是:T-SQL 代码往往很简z,因此如果某个代码块看h很难处理或重复内容较多,那么可能存在一U更单,更好的方法?

l论

如果您对我的有Q何看法,Ƣ迎随时向我发送电子邮件进行讨论,也可以就其他问题提出您的。我希望您将此作话的开场白?

其他信息Q摘?/strong> Karen 2000 q?/strong> 2 月䆾的社?/strong>

在标准开发的前沿阵地上,有一股以 SQL Server 数据库管理员 John Hindmarsh 为首的独立的新生力量。MCT、MCSE ?MCDBA 都是最值得您花旉ȝI的。John 的A献是撰写了一份详l的白皮书,概述了他对各U?SQL Server 相关标准提出的徏议。我所知道的其他唯一提出cM的文章是 Andrew Zanevsky 的《Transact-SQL Programming?ISBN 1-56592-401-0) 中的“Format and Style”一章。Andrew、SQL Server Professional 的投Eh Tom Moreau ?Paul Munkenbeck 以及 John 的朋友兼同事 Stephen James 都ؓ John 的白皮书做出qA献。下面是 John 为编写存储过E提供的CZQ?/p>

使用 SQL-92 标准q接句法?

Z提高性能Q应优先使用q接Q然后用子查询或嵌套查询?

保变量和参数的cd和大与表数据列相匹配?

保使用所有变量和参数Q或者全部删除?

可能将临时对象攄在本地?

只用在存储q程中创建的临时表?

查输入参数的有效性?

优先使用 SELECT...INTOQ然后?INSERT...SELECTQ以避免大量死锁?

l护工作需要的逻辑单元Q在可以~短的情况下Q不要创建大量或长时间运行的q程?

不要在Q何代码中使用 SELECT *?

在过E中使用~进、块、制表符和空|参阅CZ脚本Q?

T-SQL 语句要大写?

在过E中d大量注释Q确保可以识别进E。在有助于澄清处理步骤的地方使用行注释?

包括事务理Q除非要?MTS q程中调用过E。(?MTS q程~写独立的过E。)

监视 @@TRANCOUNT 以确定事务的责QU别?

避免使用 GOTOQ错误处理程序中除外?

避免使用嵌套q程?

避免隐式解析对象名称Q确保所有对象都?dbo 所有?

下蝲 412BRIAN.ZIP

链接?/strong>www.microsoft.com/downloads/details.aspx?displayla%20ng=en&familyid=B352EB1F-D3CA-44EE-893E-9E07339C1F22&displaylang=en

有关 SQL Server Professional ?Pinnacle Publishing 的详l信息,误问其 Web 站点 http://www.pinpub.com/

注意Q这不是 Microsoft Corporation ?Web 站点。Microsoft 对该 Web 站点上的内容不承担Q何责仅R?/p>

本文转蝲?2004 q?12 月䆾?SQL Server Professional。除非另行说明,否则版权所?2004 Pinnacle Publishing, Inc.。保留所有权利。SQL Server Professional ?Pinnacle Publishing 独立发行的刊物。未l?Pinnacle Publishing, Inc. 事先同意Q不得以M方式使用或复制本文的M部分Q评论文章中的简短引用除外)。如需?Pinnacle Publishing, Inc. 联系Q请拨打 1-800-788-1900?/p>

© 2005 Microsoft Corporation 版权所有。保留所有权利。用规定?/a>

原文出处:http://www.microsoft.com/china/msdn/library/data/sqlserver/sp04l9.mspx?mfr=true



竹子 2008-12-02 10:50 发表评论
]]>
SQL优化34条—开发必?/title><link>http://www.aygfsteel.com/zhuzi1987/archive/2008/12/02/243864.html</link><dc:creator>竹子</dc:creator><author>竹子</author><pubDate>Tue, 02 Dec 2008 02:42:00 GMT</pubDate><guid>http://www.aygfsteel.com/zhuzi1987/archive/2008/12/02/243864.html</guid><wfw:comment>http://www.aygfsteel.com/zhuzi1987/comments/243864.html</wfw:comment><comments>http://www.aygfsteel.com/zhuzi1987/archive/2008/12/02/243864.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/zhuzi1987/comments/commentRss/243864.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/zhuzi1987/services/trackbacks/243864.html</trackback:ping><description><![CDATA[<span style="color: red"><span style="color: #800000">  </span></span><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>1<span style="font-family: 宋体">Q?/span>      <span style="font-family: 宋体">选择最有效率的表名序</span>(<span style="font-family: 宋体">只在Z规则的优化器中有?/span>)<span style="font-family: 宋体">Q?/span></span></span> <p><span style="color: red"><span style="color: #800000">ORACLE <span style="font-family: 宋体">的解析器按照从右到左的顺序处?/span>FROM<span style="font-family: 宋体">子句中的表名Q?/span>FROM<span style="font-family: 宋体">子句中写在最后的?/span>(<span style="font-family: 宋体">基础?/span> driving table)<span style="font-family: 宋体">被最先处理,?/span>FROM<span style="font-family: 宋体">子句中包含多个表的情况下</span>,<span style="font-family: 宋体">你必选择记录条数最的表作为基表。如果有</span>3<span style="font-family: 宋体">个以上的表连接查?/span>, <span style="font-family: 宋体">那就需要选择交叉?/span>(intersection table)<span style="font-family: 宋体">作ؓ基础?/span>, <span style="font-family: 宋体">交叉表是指那个被其他表所引用的表</span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>2<span style="font-family: 宋体">Q?/span>      WHERE<span style="font-family: 宋体">子句中的q接序Q:</span></span></span></p> <p><span style="color: red"><span style="color: #800000">ORACLE<span style="font-family: 宋体">采用自下而上的顺序解?/span>WHERE<span style="font-family: 宋体">子句</span>,<span style="font-family: 宋体">Ҏq个原理</span>,<span style="font-family: 宋体">表之间的q接必须写在其他</span>WHERE<span style="font-family: 宋体">条g之前</span>, <span style="font-family: 宋体">那些可以qo掉最大数量记录的条g必须写在</span>WHERE<span style="font-family: 宋体">子句的末?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>3<span style="font-family: 宋体">Q?/span>      SELECT<span style="font-family: 宋体">子句中避免?/span> <span style="font-family: 宋体">‘</span> * <span style="font-family: 宋体">‘Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">ORACLE<span style="font-family: 宋体">在解析的q程?/span>, <span style="font-family: 宋体">会将</span>'*' <span style="font-family: 宋体">依次转换成所有的列名</span>, <span style="font-family: 宋体">q个工作是通过查询数据字典完成?/span>, <span style="font-family: 宋体">q意味着耗费更多的时?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>4<span style="font-family: 宋体">Q?/span>      <span style="font-family: 宋体">减少讉K数据库的ơ数Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">ORACLE<span style="font-family: 宋体">在内部执行了许多工作</span>: <span style="font-family: 宋体">解析</span>SQL<span style="font-family: 宋体">语句</span>, <span style="font-family: 宋体">估算索引的利用率</span>, <span style="font-family: 宋体">l定变量</span> , <span style="font-family: 宋体">L据块{;</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>5<span style="font-family: 宋体">Q?/span>      <span style="font-family: 宋体">?/span>SQL*Plus , SQL*Forms<span style="font-family: 宋体">?/span>Pro*C<span style="font-family: 宋体">中重新设|?/span>ARRAYSIZE<span style="font-family: 宋体">参数</span>, <span style="font-family: 宋体">可以增加每次数据库访问的索数据量</span> ,<span style="font-family: 宋体">gؓ</span>200</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>6<span style="font-family: 宋体">Q?/span>      <span style="font-family: 宋体">使用</span>DECODE<span style="font-family: 宋体">函数来减处理时_</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">使用</span>DECODE<span style="font-family: 宋体">函数可以避免重复扫描相同记录或重复连接相同的?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>7<span style="font-family: 宋体">Q?/span>      <span style="font-family: 宋体">整合?/span>,<span style="font-family: 宋体">无关联的数据库访问:</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">如果你有几个单的数据库查询语?/span>,<span style="font-family: 宋体">你可以把它们整合C个查询中</span>(<span style="font-family: 宋体">即它们之间没有关系</span>)</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>8<span style="font-family: 宋体">Q?/span>      <span style="font-family: 宋体">删除重复记录Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">最高效的删除重复记录方?/span> ( <span style="font-family: 宋体">因ؓ使用?/span>ROWID)<span style="font-family: 宋体">例子Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM EMP X WHERE X.EMP_NO = E.EMP_NO);</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>9<span style="font-family: 宋体">Q?/span>      <span style="font-family: 宋体">?/span>TRUNCATE<span style="font-family: 宋体">替代</span>DELETE<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">当删除表中的记录?/span>,<span style="font-family: 宋体">在通常情况?/span>, <span style="font-family: 宋体">回滚D?/span>(rollback segments ) <span style="font-family: 宋体">用来存放可以被恢复的信息</span>. <span style="font-family: 宋体">如果你没?/span>COMMIT<span style="font-family: 宋体">事务</span>,ORACLE<span style="font-family: 宋体">会将数据恢复到删除之前的状?/span>(<span style="font-family: 宋体">准确地说是恢复到执行删除命o之前的状?/span>) <span style="font-family: 宋体">而当q用</span>TRUNCATE<span style="font-family: 宋体">?/span>, <span style="font-family: 宋体">回滚D不再存放Q何可被恢复的信息</span>.<span style="font-family: 宋体">当命令运行后</span>,<span style="font-family: 宋体">数据不能被恢?/span>.<span style="font-family: 宋体">因此很少的资源被调用</span>,<span style="font-family: 宋体">执行旉也会很短</span>. (<span style="font-family: 宋体">译者按</span>: TRUNCATE<span style="font-family: 宋体">只在删除全表适用</span>,TRUNCATE<span style="font-family: 宋体">?/span>DDL<span style="font-family: 宋体">不是</span>DML)</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>10<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">量多?/span>COMMIT<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">只要有可?/span>,<span style="font-family: 宋体">在程序中量多?/span>COMMIT, <span style="font-family: 宋体">q样E序的性能得到提高</span>,<span style="font-family: 宋体">需求也会因?/span>COMMIT<span style="font-family: 宋体">所释放的资源而减?/span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">COMMIT<span style="font-family: 宋体">所释放的资?/span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">a. <span style="font-family: 宋体">回滚D上用于恢复数据的信?/span>. </span></span></p> <p><span style="color: red"><span style="color: #800000">b. <span style="font-family: 宋体">被程序语句获得的?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">c. redo log buffer <span style="font-family: 宋体">中的I间</span></span></span></p> <p><span style="color: red"><span style="color: #800000">d. ORACLE<span style="font-family: 宋体">为管理上q?/span>3<span style="font-family: 宋体">U资源中的内部花?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>11<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>Where<span style="font-family: 宋体">子句替换</span>HAVING<span style="font-family: 宋体">子句Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">避免使用</span>HAVING<span style="font-family: 宋体">子句</span>, HAVING <span style="font-family: 宋体">只会在检索出所有记录之后才对结果集q行qo</span>. <span style="font-family: 宋体">q个处理需要排?/span>,<span style="font-family: 宋体">总计{操?/span>. <span style="font-family: 宋体">如果能通过</span>WHERE<span style="font-family: 宋体">子句限制记录的数?/span>,<span style="font-family: 宋体">那就能减这斚w的开销</span>. (<span style="font-family: 宋体">?/span>oracle<span style="font-family: 宋体">?/span>)on<span style="font-family: 宋体">?/span>where<span style="font-family: 宋体">?/span>having<span style="font-family: 宋体">q三个都可以加条件的子句中,</span>on<span style="font-family: 宋体">是最先执行,</span>where<span style="font-family: 宋体">ơ之Q?/span>having<span style="font-family: 宋体">最后,因ؓ</span>on<span style="font-family: 宋体">是先把不W合条g的记录过滤后才进行统计,它就可以减少中间q算要处理的数据Q按理说应该速度是最快的Q?/span>where<span style="font-family: 宋体">也应该比</span>having<span style="font-family: 宋体">快点的,因ؓ它过滤数据后才进?/span>sum<span style="font-family: 宋体">Q在两个表联接时才用</span>on<span style="font-family: 宋体">的,所以在一个表的时候,剩?/span>where<span style="font-family: 宋体">?/span>having<span style="font-family: 宋体">比较了。在q单表查询统计的情况下,如果要过滤的条g没有涉及到要计算字段Q那它们的结果是一LQ只?/span>where<span style="font-family: 宋体">可以使用</span>rushmore<span style="font-family: 宋体">技术,?/span>having<span style="font-family: 宋体">׃能,在速度上后者要慢如果要涉及到计的字段Q就表示在没计算之前Q这个字D늚值是不确定的Q根据上写的工作流E,</span>where<span style="font-family: 宋体">的作用时间是在计之前就完成的,?/span>having<span style="font-family: 宋体">是在计后才v作用的,所以在q种情况下,两者的l果会不同。在多表联接查询Ӟ</span>on<span style="font-family: 宋体">?/span>where<span style="font-family: 宋体">更早起作用。系l首先根据各个表之间的联接条Ӟ把多个表合成一个时表后,再由</span>where<span style="font-family: 宋体">q行qoQ然后再计算Q计完后再?/span>having<span style="font-family: 宋体">q行qo。由此可见,要想qo条g起到正确的作用,首先要明白这个条件应该在什么时候v作用Q然后再军_攑֜那里</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>12<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">减少对表的查询:</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">在含有子查询?/span>SQL<span style="font-family: 宋体">语句?/span>,<span style="font-family: 宋体">要特别注意减对表的查询</span>.<span style="font-family: 宋体">例子Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">     SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT</span></span></p> <p><span style="color: red"><span style="color: #800000">TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>13<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">通过内部函数提高</span>SQL<span style="font-family: 宋体">效率</span>.<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">复杂?/span>SQL<span style="font-family: 宋体">往往牺牲了执行效?/span>. <span style="font-family: 宋体">能够掌握上面的运用函数解决问题的Ҏ在实际工作中是非常有意义?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>14<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">使用表的别名</span>(Alias)<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">当在</span>SQL<span style="font-family: 宋体">语句中连接多个表?/span>, <span style="font-family: 宋体">请用表的别名ƈ把别名前~于每?/span>Column<span style="font-family: 宋体">?/span>.<span style="font-family: 宋体">q样一?/span>,<span style="font-family: 宋体">可以减解析的旉q减那些由</span>Column<span style="font-family: 宋体">歧义引v的语法错?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>15<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>EXISTS<span style="font-family: 宋体">替代</span>IN<span style="font-family: 宋体">、用</span>NOT EXISTS<span style="font-family: 宋体">替代</span>NOT IN<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">在许多基于基表的查询?/span>,<span style="font-family: 宋体">Z满一个条?/span>,<span style="font-family: 宋体">往往需要对另一个表q行联接</span>.<span style="font-family: 宋体">在这U情况下</span>, <span style="font-family: 宋体">使用</span>EXISTS(<span style="font-family: 宋体">?/span>NOT EXISTS)<span style="font-family: 宋体">通常提高查询的效率</span>. <span style="font-family: 宋体">在子查询?/span>,NOT IN<span style="font-family: 宋体">子句执行一个内部的排序和合q?/span>. <span style="font-family: 宋体">无论在哪U情况下</span>,NOT IN<span style="font-family: 宋体">都是最低效?/span> (<span style="font-family: 宋体">因ؓ它对子查询中的表执行了一个全表遍?/span>). <span style="font-family: 宋体">Z避免使用</span>NOT IN ,<span style="font-family: 宋体">我们可以把它改写成外q接</span>(Outer Joins)<span style="font-family: 宋体">?/span>NOT EXISTS.</span></span></p> <p><span style="font-family: 宋体"><span style="color: red"><span style="color: #800000">例子Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q高效)</span>SELECT * FROM EMP (<span style="font-family: 宋体">基础?/span>) WHERE EMPNO > 0 AND EXISTS (SELECT <span style="font-family: 宋体">‘</span>X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = <span style="font-family: 宋体">‘</span>MELB')</span></span></p> <p><span style="color: red"><span style="color: #800000">(<span style="font-family: 宋体">低效</span>)SELECT * FROM EMP (<span style="font-family: 宋体">基础?/span>) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = <span style="font-family: 宋体">‘</span>MELB')</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>16<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">识别</span>'<span style="font-family: 宋体">低效执行</span>'<span style="font-family: 宋体">?/span>SQL<span style="font-family: 宋体">语句Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">虽然目前各种关于</span>SQL<span style="font-family: 宋体">优化的图形化工具层出不穷</span>,<span style="font-family: 宋体">但是写出自己?/span>SQL<span style="font-family: 宋体">工具来解决问题始l是一个最好的ҎQ?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT EXECUTIONS , DISK_READS, BUFFER_GETS, </span></span></p> <p><span style="color: red"><span style="color: #800000">ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio, </span></span></p> <p><span style="color: red"><span style="color: #800000">ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run, </span></span></p> <p><span style="color: red"><span style="color: #800000">SQL_TEXT </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM V$SQLAREA </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE EXECUTIONS>0 </span></span></p> <p><span style="color: red"><span style="color: #800000">AND BUFFER_GETS > 0 </span></span></p> <p><span style="color: red"><span style="color: #800000">AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8 </span></span></p> <p><span style="color: red"><span style="color: #800000">ORDER BY 4 DESC;</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>17<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">用烦引提高效率:</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">索引是表的一个概念部?/span>,<span style="font-family: 宋体">用来提高索数据的效率Q?/span>ORACLE<span style="font-family: 宋体">使用了一个复杂的自^?/span>B-tree<span style="font-family: 宋体">l构</span>. <span style="font-family: 宋体">通常</span>,<span style="font-family: 宋体">通过索引查询数据比全表扫描要?/span>. <span style="font-family: 宋体">?/span>ORACLE<span style="font-family: 宋体">扑և执行查询?/span>Update<span style="font-family: 宋体">语句的最佌\径时</span>, ORACLE<span style="font-family: 宋体">优化器将使用索引</span>. <span style="font-family: 宋体">同样在联l多个表时用烦引也可以提高效率</span>. <span style="font-family: 宋体">另一个用烦引的好处?/span>,<span style="font-family: 宋体">它提供了主键</span>(primary key)<span style="font-family: 宋体">的唯一性验?/span>.<span style="font-family: 宋体">。那?/span>LONG<span style="font-family: 宋体">?/span>LONG RAW<span style="font-family: 宋体">数据cd</span>, <span style="font-family: 宋体">你可以烦引几乎所有的?/span>. <span style="font-family: 宋体">通常</span>, <span style="font-family: 宋体">在大型表中用烦引特别有?/span>. <span style="font-family: 宋体">当然</span>,<span style="font-family: 宋体">你也会发?/span>, <span style="font-family: 宋体">在扫描小表时</span>,<span style="font-family: 宋体">使用索引同样能提高效?/span>. <span style="font-family: 宋体">虽然使用索引能得到查询效率的提高</span>,<span style="font-family: 宋体">但是我们也必L意到它的代h</span>. <span style="font-family: 宋体">索引需要空间来存储</span>,<span style="font-family: 宋体">也需要定期维?/span>, <span style="font-family: 宋体">每当有记录在表中增减或烦引列被修Ҏ</span>, <span style="font-family: 宋体">索引本n也会被修?/span>. <span style="font-family: 宋体">q意味着每条记录?/span>INSERT , DELETE , UPDATE<span style="font-family: 宋体">ؓ此多付出</span>4 , 5 <span style="font-family: 宋体">ơ的盘</span>I/O . <span style="font-family: 宋体">因ؓ索引需要额外的存储I间和处?/span>,<span style="font-family: 宋体">那些不必要的索引反而会使查询反应时间变?/span>.<span style="font-family: 宋体">。定期的重构索引是有必要?/span>.<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>18<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>EXISTS<span style="font-family: 宋体">替换</span>DISTINCT<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">当提交一个包含一对多表信?/span>(<span style="font-family: 宋体">比如部门表和雇员?/span>)<span style="font-family: 宋体">的查询时</span>,<span style="font-family: 宋体">避免?/span>SELECT<span style="font-family: 宋体">子句中?/span>DISTINCT. <span style="font-family: 宋体">一般可以考虑?/span>EXIST<span style="font-family: 宋体">替换</span>, EXISTS <span style="font-family: 宋体">使查询更?/span>,<span style="font-family: 宋体">因ؓ</span>RDBMS<span style="font-family: 宋体">核心模块在子查询的条g一旦满_</span>,<span style="font-family: 宋体">立刻q回l果</span>. <span style="font-family: 宋体">例子Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">       (<span style="font-family: 宋体">低效</span>): </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE D.DEPT_NO = E.DEPT_NO </span></span></p> <p><span style="color: red"><span style="color: #800000">(<span style="font-family: 宋体">高效</span>): </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>19<span style="font-family: 宋体">Q?/span> sql<span style="font-family: 宋体">语句用大写的Q因?/span>oracle<span style="font-family: 宋体">L先解?/span>sql<span style="font-family: 宋体">语句Q把写的字母{换成大写的再执行</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>20<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>java<span style="font-family: 宋体">代码中尽量少用连接符“Q?#8221;q接字符Ԍ</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>21<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">避免在烦引列上?/span>NOT <span style="font-family: 宋体">通常Q </span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">我们要避免在索引列上使用</span>NOT, NOT<span style="font-family: 宋体">会生在和在索引列上使用函数相同的媄?/span>. <span style="font-family: 宋体">?/span>ORACLE<span style="font-family: 宋体">”遇到”</span>NOT,<span style="font-family: 宋体">他就会停止用烦引{而执行全表扫?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>22<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">避免在烦引列上用计.</span></span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE<span style="font-family: 宋体">子句中,如果索引列是函数的一部分Q优化器不使用索引而用全表扫描.</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">举例</span>: </span></span></p> <p><span style="font-family: 宋体"><span style="color: red"><span style="color: #800000">低效Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT … FROM DEPT WHERE SAL * 12 > 25000; </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">高效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT … FROM DEPT WHERE SAL > 25000/12;</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>23<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>>=<span style="font-family: 宋体">替代</span>></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">高效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT * FROM EMP WHERE DEPTNO >=4 </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">低效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT * FROM EMP WHERE DEPTNO >3 </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">两者的区别在于</span>, <span style="font-family: 宋体">前?/span>DBMS<span style="font-family: 宋体">直接蟩到第一?/span>DEPT<span style="font-family: 宋体">{于</span>4<span style="font-family: 宋体">的记录而后者将首先定位?/span>DEPTNO=3<span style="font-family: 宋体">的记录ƈ且向前扫描到W一?/span>DEPT<span style="font-family: 宋体">大于</span>3<span style="font-family: 宋体">的记?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>24<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>UNION<span style="font-family: 宋体">替换</span>OR (<span style="font-family: 宋体">适用于烦引列</span>)</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">通常情况?/span>, <span style="font-family: 宋体">?/span>UNION<span style="font-family: 宋体">替换</span>WHERE<span style="font-family: 宋体">子句中的</span>OR<span style="font-family: 宋体">会起到较好的效?/span>. <span style="font-family: 宋体">对烦引列使用</span>OR<span style="font-family: 宋体">造成全表扫描</span>. <span style="font-family: 宋体">注意</span>, <span style="font-family: 宋体">以上规则只针对多个烦引列有效</span>. <span style="font-family: 宋体">如果?/span>column<span style="font-family: 宋体">没有被烦?/span>, <span style="font-family: 宋体">查询效率可能会因Z没有选择</span>OR<span style="font-family: 宋体">而降?/span>. <span style="font-family: 宋体">在下面的例子?/span>, LOC_ID <span style="font-family: 宋体">?/span>REGION<span style="font-family: 宋体">上都建有索引</span>. </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">高效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT LOC_ID , LOC_DESC , REGION </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM LOCATION </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE LOC_ID = 10 </span></span></p> <p><span style="color: red"><span style="color: #800000">UNION</span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT LOC_ID , LOC_DESC , REGION </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM LOCATION </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE REGION = “MELBOURNE” </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">低效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT LOC_ID , LOC_DESC , REGION </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM LOCATION </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE LOC_ID = 10 OR REGION = “MELBOURNE” </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">如果你坚持要?/span>OR, <span style="font-family: 宋体">那就需要返回记录最的索引列写在最前面</span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>25<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>IN<span style="font-family: 宋体">来替?/span>OR </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">q是一条简单易记的规则Q但是实际的执行效果q须验,?/span>ORACLE8i<span style="font-family: 宋体">下,两者的执行路径g是相同的Q </span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">低效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30 </span></span></p> <p><span style="font-family: 宋体"><span style="color: red"><span style="color: #800000">高效</span></span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>26<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">避免在烦引列上?/span>IS NULL<span style="font-family: 宋体">?/span>IS NOT NULL</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">避免在烦引中使用M可以为空的列Q?/span>ORACLE<span style="font-family: 宋体">无法用该索引Q对于单列烦引,如果列包含空|索引中将不存在此记录</span>. <span style="font-family: 宋体">对于复合索引Q如果每个列都ؓI,索引中同样不存在此记?/span>.<span style="font-family: 宋体"> 如果臛_有一个列不ؓI,则记录存在于索引中.举例</span>: <span style="font-family: 宋体">如果唯一性烦引徏立在表的</span>A<span style="font-family: 宋体">列和</span>B<span style="font-family: 宋体">列上</span>, <span style="font-family: 宋体">q且表中存在一条记录的</span>A,B<span style="font-family: 宋体">gؓ</span>(123,null) , ORACLE<span style="font-family: 宋体">不接受下一条具有相?/span>A,B<span style="font-family: 宋体">|</span>123,null<span style="font-family: 宋体">Q的记录</span>(<span style="font-family: 宋体">插入</span>). <span style="font-family: 宋体">然而如果所有的索引列都为空Q?/span>ORACLE<span style="font-family: 宋体">认为整个键gؓI空不等于空</span>. <span style="font-family: 宋体">因此你可以插?/span>1000 <span style="font-family: 宋体">条具有相同键值的记录</span>,<span style="font-family: 宋体">当然它们都是I?/span>! <span style="font-family: 宋体">因ؓIg存在于烦引列?/span>,<span style="font-family: 宋体">所?/span>WHERE<span style="font-family: 宋体">子句中对索引列进行空值比较将?/span>ORACLE<span style="font-family: 宋体">停用该烦?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">低效</span>: (<span style="font-family: 宋体">索引失效</span>) </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL; </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">高效</span>: (<span style="font-family: 宋体">索引有效</span>) </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>27<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">L使用索引的第一个列Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">如果索引是徏立在多个列上</span>, <span style="font-family: 宋体">只有在它的第一个列</span>(leading column)<span style="font-family: 宋体">?/span>where<span style="font-family: 宋体">子句引用?/span>,<span style="font-family: 宋体">优化器才会选择使用该烦?/span>. <span style="font-family: 宋体">q也是一条简单而重要的规则Q当仅引用烦引的W二个列?/span>,<span style="font-family: 宋体">优化器用了全表扫描而忽略了索引</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>28<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>UNION-ALL <span style="font-family: 宋体">替换</span>UNION ( <span style="font-family: 宋体">如果有可能的?/span>)<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">?/span>SQL <span style="font-family: 宋体">语句需?/span>UNION<span style="font-family: 宋体">两个查询l果集合?/span>,<span style="font-family: 宋体">q两个结果集合会?/span>UNION-ALL<span style="font-family: 宋体">的方式被合ƈ</span>, <span style="font-family: 宋体">然后在输出最l结果前q行排序</span>. <span style="font-family: 宋体">如果?/span>UNION ALL<span style="font-family: 宋体">替代</span>UNION, <span style="font-family: 宋体">q样排序׃是必要了</span>. <span style="font-family: 宋体">效率׃因此得到提高</span>. <span style="font-family: 宋体">需要注意的是,</span>UNION ALL <span style="font-family: 宋体">重复输Z个结果集合中相同记录</span>. <span style="font-family: 宋体">因此各位q是要从业务需求分析?/span>UNION ALL<span style="font-family: 宋体">的可行?/span>. UNION <span style="font-family: 宋体">对l果集合排序</span>,<span style="font-family: 宋体">q个操作会用到</span>SORT_AREA_SIZE<span style="font-family: 宋体">q块内存</span>. <span style="font-family: 宋体">对于q块内存的优化也是相当重要的</span>. <span style="font-family: 宋体">下面?/span>SQL<span style="font-family: 宋体">可以用来查询排序的消耗量</span></span></span></p> <p><span style="font-family: 宋体"><span style="color: red"><span style="color: #800000">低效Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT ACCT_NUM, BALANCE_AMT </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM DEBIT_TRANSACTIONS </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE TRAN_DATE = '31-DEC-95' </span></span></p> <p><span style="color: red"><span style="color: #800000">UNION</span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT ACCT_NUM, BALANCE_AMT </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM DEBIT_TRANSACTIONS </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE TRAN_DATE = '31-DEC-95' </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">高效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT ACCT_NUM, BALANCE_AMT </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM DEBIT_TRANSACTIONS </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE TRAN_DATE = '31-DEC-95' </span></span></p> <p><span style="color: red"><span style="color: #800000">UNION ALL </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT ACCT_NUM, BALANCE_AMT </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM DEBIT_TRANSACTIONS </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE TRAN_DATE = '31-DEC-95'</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>29<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">?/span>WHERE<span style="font-family: 宋体">替代</span>ORDER BY<span style="font-family: 宋体">Q?/span></span></span></p> <p><span style="color: red"><span style="color: #800000">ORDER BY <span style="font-family: 宋体">子句只在两种严格的条件下使用索引</span>. </span></span></p> <p><span style="color: red"><span style="color: #800000">ORDER BY<span style="font-family: 宋体">中所有的列必d含在相同的烦引中q保持在索引中的排列序</span>. </span></span></p> <p><span style="color: red"><span style="color: #800000">ORDER BY<span style="font-family: 宋体">中所有的列必d义ؓ非空</span>. </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE<span style="font-family: 宋体">子句使用的烦引和</span>ORDER BY<span style="font-family: 宋体">子句中所使用的烦引不能ƈ?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">例如</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">?/span>DEPT<span style="font-family: 宋体">包含以下?/span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">DEPT_CODE PK NOT NULL </span></span></p> <p><span style="color: red"><span style="color: #800000">DEPT_DESC NOT NULL </span></span></p> <p><span style="color: red"><span style="color: #800000">DEPT_TYPE NULL</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">低效</span>: (<span style="font-family: 宋体">索引不被使用</span>) </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">高效</span>: (<span style="font-family: 宋体">使用索引</span>) </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>30<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">避免改变索引列的cd</span>.:</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">当比较不同数据类型的数据?/span>, ORACLE<span style="font-family: 宋体">自动对列q行单的cd转换</span>. </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">假设</span> EMPNO<span style="font-family: 宋体">是一个数值类型的索引?/span>. </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT … FROM EMP WHERE EMPNO = ‘123' </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">实际?/span>,<span style="font-family: 宋体">l过</span>ORACLE<span style="font-family: 宋体">cd转换</span>, <span style="font-family: 宋体">语句转化?/span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT … FROM EMP WHERE EMPNO = TO_NUMBER(‘123') </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">q运的是</span>,<span style="font-family: 宋体">cd转换没有发生在烦引列?/span>,<span style="font-family: 宋体">索引的用途没有被改变</span>. </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">现在</span>,<span style="font-family: 宋体">假设</span>EMP_TYPE<span style="font-family: 宋体">是一个字W类型的索引?/span>. </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT … FROM EMP WHERE EMP_TYPE = 123 </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">q个语句?/span>ORACLE<span style="font-family: 宋体">转换?/span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT … FROM EMP WHERETO_NUMBER(EMP_TYPE)=123 </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">因ؓ内部发生的类型{?/span>, <span style="font-family: 宋体">q个索引不会被用到</span>! <span style="font-family: 宋体">Z避免</span>ORACLE<span style="font-family: 宋体">对你?/span>SQL<span style="font-family: 宋体">q行隐式的类型{?/span>, <span style="font-family: 宋体">最好把cd转换用显式表现出?/span>. <span style="font-family: 宋体">注意当字W和数值比较时</span>, ORACLE<span style="font-family: 宋体">会优先{换数值类型到字符cd</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>31<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">需要当心的</span>WHERE<span style="font-family: 宋体">子句</span>:</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">某些</span>SELECT <span style="font-family: 宋体">语句中的</span>WHERE<span style="font-family: 宋体">子句不用烦?/span>. <span style="font-family: 宋体">q里有一些例?/span>. </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">在下面的例子?/span>, (1)<span style="font-family: 宋体">‘</span>!=' <span style="font-family: 宋体">不使用索引</span>. <span style="font-family: 宋体">C</span>, <span style="font-family: 宋体">索引只能告诉你什么存在于表中</span>, <span style="font-family: 宋体">而不能告诉你什么不存在于表?/span>. (2) <span style="font-family: 宋体">‘</span>||'<span style="font-family: 宋体">是字W连接函?/span>. <span style="font-family: 宋体">p其他函数那样</span>, <span style="font-family: 宋体">停用了烦?/span>. (3) <span style="font-family: 宋体">‘</span>+'<span style="font-family: 宋体">是数学函?/span>. <span style="font-family: 宋体">p其他数学函数那样</span>, <span style="font-family: 宋体">停用了烦?/span>. (4)<span style="font-family: 宋体">相同的烦引列不能互相比较</span>,<span style="font-family: 宋体">q将会启用全表扫?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>32<span style="font-family: 宋体">Q?/span> a. <span style="font-family: 宋体">如果索数据量过</span>30%<span style="font-family: 宋体">的表中记录数</span>.<span style="font-family: 宋体">使用索引没有显著的效率提高</span>. </span></span></p> <p><span style="color: red"><span style="color: #800000">b. <span style="font-family: 宋体">在特定情况下</span>, <span style="font-family: 宋体">使用索引也许会比全表扫描?/span>, <span style="font-family: 宋体">但这是同一个数量上的区别</span>. <span style="font-family: 宋体">而通常情况?/span>,<span style="font-family: 宋体">使用索引比全表扫描要块几倍乃臛_千?/span>!</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>33<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">避免使用耗费资源的操?/span>:</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">带有</span>DISTINCT,UNION,MINUS,INTERSECT,ORDER BY<span style="font-family: 宋体">?/span>SQL<span style="font-family: 宋体">语句会启?/span>SQL<span style="font-family: 宋体">引擎</span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">执行耗费资源的排?/span>(SORT)<span style="font-family: 宋体">功能</span>. DISTINCT<span style="font-family: 宋体">需要一ơ排序操?/span>, <span style="font-family: 宋体">而其他的臛_需要执行两ơ排?/span>. <span style="font-family: 宋体">通常</span>, <span style="font-family: 宋体">带有</span>UNION, MINUS , INTERSECT<span style="font-family: 宋体">?/span>SQL<span style="font-family: 宋体">语句都可以用其他方式重写</span>. <span style="font-family: 宋体">如果你的数据库的</span>SORT_AREA_SIZE<span style="font-family: 宋体">调配得好</span>, <span style="font-family: 宋体">使用</span>UNION , MINUS, INTERSECT<span style="font-family: 宋体">也是可以考虑?/span>, <span style="font-family: 宋体">毕竟它们的可L很?/span></span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">Q?/span>34<span style="font-family: 宋体">Q?/span> <span style="font-family: 宋体">优化</span>GROUP BY:</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">提高</span>GROUP BY <span style="font-family: 宋体">语句的效?/span>, <span style="font-family: 宋体">可以通过不需要的记录?/span>GROUP BY <span style="font-family: 宋体">之前qo?/span>.<span style="font-family: 宋体">下面两个查询q回相同l果但第二个明显快了许?/span>.</span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">低效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT JOB , AVG(SAL) </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM EMP </span></span></p> <p><span style="color: red"><span style="color: #800000">GROUP JOB </span></span></p> <p><span style="color: red"><span style="color: #800000">HAVING JOB = ‘PRESIDENT' </span></span></p> <p><span style="color: red"><span style="color: #800000">OR JOB = ‘MANAGER' </span></span></p> <p><span style="color: red"><span style="color: #800000"><span style="font-family: 宋体">高效</span>: </span></span></p> <p><span style="color: red"><span style="color: #800000">SELECT JOB , AVG(SAL) </span></span></p> <p><span style="color: red"><span style="color: #800000">FROM EMP </span></span></p> <p><span style="color: red"><span style="color: #800000">WHERE JOB = ‘PRESIDENT' </span></span></p> <p><span style="color: red"><span style="color: #800000">OR JOB = ‘MANAGER' </span></span></p> <p><span style="color: red"><span style="color: #800000">GROUP JOB</span></span></p> <img src ="http://www.aygfsteel.com/zhuzi1987/aggbug/243864.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/zhuzi1987/" target="_blank">竹子</a> 2008-12-02 10:42 <a href="http://www.aygfsteel.com/zhuzi1987/archive/2008/12/02/243864.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库性能优化有哪些措?http://www.aygfsteel.com/zhuzi1987/archive/2008/11/20/241552.html竹子竹子Thu, 20 Nov 2008 01:47:00 GMThttp://www.aygfsteel.com/zhuzi1987/archive/2008/11/20/241552.htmlhttp://www.aygfsteel.com/zhuzi1987/comments/241552.htmlhttp://www.aygfsteel.com/zhuzi1987/archive/2008/11/20/241552.html#Feedback0http://www.aygfsteel.com/zhuzi1987/comments/commentRss/241552.htmlhttp://www.aygfsteel.com/zhuzi1987/services/trackbacks/241552.html 


l l 数据库回滚段是否_Q?


l l 是否需要徏立ORACLE数据库烦引、聚集、散列?


l l pȝ全局区(SGAQ大是否够?


l l SQL语句是否高效Q?


2?、数据仓库系l(Data WarehousingQ,q种信息pȝ的主要Q务是从ORACLE的v量数据中q行查询Q得到数据之间的某些规律。数据库理员需要ؓq种cd的ORACLE数据库着重考虑下述参数Q?


l l 是否采用B*-索引或者bitmap索引Q?


l l 是否采用q行SQL查询以提高查询效率?


l l 是否采用PL/SQL函数~写存储q程Q?


l l 有必要的话,需要徏立ƈ行数据库提高数据库的查询效率


SQL语句的调整原?


SQL语言是一U灵zȝ语言Q相同的功能可以使用不同的语句来实现Q但是语句的执行效率是很不相同的。程序员可以使用EXPLAIN PLAN语句来比较各U实现方案,q出最优的实现Ҏ。d来讲Q程序员写SQL语句需要满虑如下规则Q?


1?、尽量用烦引。试比较下面两条SQL语句Q?


语句AQSELECT dname, deptno FROM dept WHERE deptno NOT IN


(SELECT deptno FROM emp);


语句BQSELECT dname, deptno FROM dept WHERE NOT EXISTS


(SELECT deptno FROM emp WHERE dept.deptno = emp.deptno);


q两条查询语句实现的l果是相同的Q但是执行语句A的时候,ORACLE会对整个emp表进行扫描,没有使用建立在emp表上的deptno索引Q执行语句B的时候,׃在子查询中用了联合查询QORACLE只是对emp表进行的部分数据扫描Qƈ利用了deptno列的索引Q所以语句B的效率要比语句A的效率高一些?


2?、选择联合查询的联合次序。考虑下面的例子:


SELECT stuff FROM taba a, tabb b, tabc c


WHERE a.acol between :alow and :ahigh


AND b.bcol between :blow and :bhigh


AND c.ccol between :clow and :chigh


AND a.key1 = b.key1


AMD a.key2 = c.key2;


q个SQL例子中,E序员首先需要选择要查询的主表Q因Z表要q行整个表数据的扫描Q所以主表应该数据量最,所以例子中表A的acol列的范围应该比表B和表C相应列的范围?


3?、在子查询中慎重使用IN或者NOT IN语句Q用where (NOT) exists的效果要好的多?


4?、慎重用视囄联合查询Q尤其是比较复杂的视图之间的联合查询。一般对视图的查询最好都分解为对数据表的直接查询效果要好一些?


5?、可以在参数文g中设|SHARED_POOL_RESERVED_SIZE参数Q这个参数在SGA׃n池中保留一个连l的内存I间Q连l的内存I间有益于存攑֤的SQLE序包?


6?、ORACLE公司提供的DBMS_SHARED_POOLE序可以帮助E序员将某些l常使用的存储过E?#8220;?#8221;在SQLZ而不被换出内存,E序员对于经怋用ƈ且占用内存很多的存储q程“?#8221;到内存中有利于提高最l用L响应旉?


CPU参数的调?


CPU是服务器的一w要资源,服务器良好的工作状态是在工作高峰时CPU的用率?0Q以上。如果空闲时间CPU使用率就?0Q以上,说明服务器缺乏CPU资源Q如果工作高峰时CPU使用率仍然很低,说明服务器CPU资源q比较富余?


使用操作相同命o可以看到CPU的用情况,一般UNIX操作pȝ的服务器Q可以用sar –u命o查看CPU的用率QNT操作pȝ的服务器Q可以用NT的性能理器来查看CPU的用率?


数据库管理员可以通过查看v$sysstat数据字典?#8220;CPU used by this session”l计得知ORACLE数据库用的CPU旉Q查?#8220;OS User level CPU time”l计得知操作系l用h下的CPU旉Q查?#8220;OS System call CPU time”l计得知操作系l系l态下的CPU旉Q操作系lȝCPU旉是用户态和pȝ态时间之和,如果ORACLE数据库用的CPU旉占操作系lȝCPU旉90Q以上,说明服务器CPU基本上被ORACLE数据库用着Q这是合理,反之Q说明服务器CPU被其它程序占用过多,ORACLE数据库无法得到更多的CPU旉?


数据库管理员q可以通过查看v$sesstat数据字典来获得当前连接ORACLE数据库各个会话占用的CPU旉Q从而得知什么会话耗用服务器CPU比较多?


出现CPU资源不的情冉|很多的:SQL语句的重解析、低效率的SQL语句、锁冲突都会引vCPU资源不?


1、数据库理员可以执行下q语句来查看SQL语句的解析情况:


SELECT * FROM V$SYSSTAT


WHERE NAME IN


('parse time cpu', 'parse time elapsed', 'parse count (hard)');


q里parse time cpu是系l服务时_parse time elapsed是响应时_用户{待旉


waite time = parse time elapsed – parse time cpu


由此可以得到用户SQL语句q_解析{待旉Qwaite time / parse count。这个^均等待时间应该接q于0Q如果^均解析等待时间过长,数据库管理员可以通过下述语句


SELECT SQL_TEXT, PARSE_CALLS, EXECUTIONS FROM V$SQLAREA


ORDER BY PARSE_CALLS;


来发现是什么SQL语句解析效率比较低。程序员可以优化q些语句Q或者增加ORACLE参数SESSION_CACHED_CURSORS的倹{?


2、数据库理员还可以通过下述语句Q?


SELECT BUFFER_GETS, EXECUTIONS, SQL_TEXT FROM V$SQLAREA;


查看低效率的SQL语句Q优化这些语句也有助于提高CPU的利用率?


3?、数据库理员可以通过v$system_event数据字典中的“latch free”l计Ҏ看ORACLE数据库的冲突情况Q如果没有冲H的话,latch free查询出来没有l果。如果冲H太大的话,数据库管理员可以降低spin_count参数|来消除高的CPU使用率?


内存参数的调?


内存参数的调整主要是指ORACLE数据库的pȝ全局区(SGAQ的调整。SGA主要׃部分构成Q共享池、数据缓冲区、日志缓冲区?


1?1?׃n池由两部分构成:׃nSQL区和数据字典~冲区,׃nSQL区是存放用户SQL命o的区域,数据字典~冲区存放数据库q行的动态信息。数据库理员通过执行下述语句Q?


select (sum(pins - reloads)) / sum(pins) "Lib Cache" from v$librarycache;


来查看共享SQL区的使用率。这个用率应该?0Q以上,否则需要增加共享池的大。数据库理员还可以执行下述语句Q?


select (sum(gets - getmisses - usage - fixed)) / sum(gets) "Row Cache" from v$rowcache;


查看数据字典~冲区的使用率,q个使用率也应该?0Q以上,否则需要增加共享池的大?


2?2?数据~冲区。数据库理员可以通过下述语句Q?


SELECT name, value FROM v$sysstat WHERE name IN ('db block gets', 'consistent gets','physical reads');


来查看数据库数据~冲区的使用情况。查询出来的l果可以计算出来数据~冲区的使用命中率=1 - ( physical reads / (db block gets + consistent gets) )?


q个命中率应该在90Q以上,否则需要增加数据缓冲区的大?


3?3?日志~冲区。数据库理员可以通过执行下述语句Q?


select name,value from v$sysstat where name in ('redo entries','redo log space requests');查看日志~冲区的使用情况。查询出的结果可以计出日志~冲区的甌p|率:

甌p|率=requests/entriesQ申请失败率应该接近?Q否则说明日志缓冲区开讑֤,需要增加ORACLE数据库的日志~冲区?/span>

竹子 2008-11-20 09:47 发表评论
]]>
oracle性能调优?---Oracle9i 的查询优?/title><link>http://www.aygfsteel.com/zhuzi1987/archive/2008/11/20/241551.html</link><dc:creator>竹子</dc:creator><author>竹子</author><pubDate>Thu, 20 Nov 2008 01:46:00 GMT</pubDate><guid>http://www.aygfsteel.com/zhuzi1987/archive/2008/11/20/241551.html</guid><wfw:comment>http://www.aygfsteel.com/zhuzi1987/comments/241551.html</wfw:comment><comments>http://www.aygfsteel.com/zhuzi1987/archive/2008/11/20/241551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/zhuzi1987/comments/commentRss/241551.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/zhuzi1987/services/trackbacks/241551.html</trackback:ping><description><![CDATA[<div id="wmqeeuq" class="t_msgfont" id="postmessage_7119255" style="color: #800000">本文描述?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=Oracle">Oracle</span> 的查询优?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%B3%CC%D0%F2">E序</span>Q它?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%CA%FD%BE%DD%BF%E2"><span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%CA%FD%BE%DD">数据</span>?/span>的关键组Ӟ能让<span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=Oracle">Oracle</span> ?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%D3%C3%BB%A7">用户</span>获得极佳的执行性能?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=Oracle">Oracle</span> 的查询优?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%BC%BC%CA%F5">技?/span>?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%B9%A6%C4%DC">功能</span>上无与u比,本文详细讨论了查询优化的所有重要领域?<br /> <br />   ?<br /> <br />   什么是查询优化E序Q?<br /> <br />   查询优化对于关系数据库的性能Q特别是对于执行复杂SQL 语句的性能而言臛_重要。查询优化程序确定执行每一ơ查询的最佳策略?<br /> <br />   例如Q查询优化程序选择对于指定的查询是否用烦引,以及在联接多个表旉用哪一U联接技术。这cd{对SQL 语句的执行性能有很大的影响Q查询优化对于每一U?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%D3%A6%D3%C3">应用</span>E序都是关键技术,<span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%D3%A6%D3%C3">应用</span>E序涉及的范围从操作<span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%CF%B5%CD%B3">pȝ</span>到数据仓库,从分?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%CF%B5%CD%B3">pȝ</span>到内?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%B9%DC%C0%ED">理</span><span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%CF%B5%CD%B3">pȝ</span>。查询优化程序对?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%D3%A6%D3%C3">应用</span>E序和最l用h完全透明的?<br /> <br />   ׃应用E序可能生成非常复杂的SQL 语句, 查询优化E序必须_ֿ构徏、功能强大,以保障良好的执行性能。例如,查询优化E序可{换SQL 语句Q复杂的语句{换成为等L但执行性能更好的SQL 语句。查询优化程序的典型特征是基于开销。在Z开销的优化策略中Q对于给定查询生成多个执行计划,然后Ҏ个计划估开销。查询优化程序选用估算开销最低的计划?<br /> <br />   Oracle 在查询优化方面提供了什么? <br /> <br />   Oracle 的优化程序可U是业界最成功的优化程序。基于开销的优化程序自1992 q随Oracle7 推出后,通过10 q的丰富的实际用L验,不断得到提高和改q。好的查询优化程序不是基于纯_的理论假设及谓词在实验室中开发出来的Q而是通过适合实际用户需求开发和合出来的?br /> <br />   Oracle 的查询优化程序比M其他查询优化E序在数据库应用E序的应用都要多Q而且Oracle 的优化程序一直由于实际应用的反馈而得到改q?<br /> <br />   Oracle 的优化程序包? 大主要部分(本文在以下章节详细讨论q些部分Q: <br /> <br />   SQL 语句转换Q在查询优化中Oracle 使用一pd_深技术对SQL 语句q行转换。查询优化的q一步骤的目的是原有的SQL 语句转换成ؓ语义相同而处理效率更高的SQL 语句?<br /> <br />   执行计划选择Q对于每个SQL 语句, 优化E序选择一个执行计划(可用Oracle 的EXPLAIN PLAN <span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%B9%A4%BE%DF">工具</span>或通过Oracle ?#8220;v$sql_plan” 视图查看Q。执行计划描qC执行SQL 时的所有步骤,如访问表的顺序;如何这些表联接在一P以及是否通过索引来访问这些表。优化程序ؓ每个SQL 语句设计许多可能的执行计划,q出最好的一个?<br /> <br />   开销模型与统计:Oracle 的优化程序依赖于执行SQL 语句的所有单个操作的开销估算。想要优化程序能选出最好的执行计划Q需要最好的开销估算Ҏ。开销估算需要详l了解某些知识,q些知识包括Q明白每个查询所需的I/O、CPU ?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%C4%DA%B4%E6">内存</span><span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%D7%CA%D4%B4">资源</span>以及数据库对象相关的l计信息Q表、烦引和物化视图Q,q有有关g<span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%B7%FE%CE%F1%C6%F7"><span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%B7%FE%CE%F1">服务</span>?/span>q_的性能信息。收集这些统计和性能信息的过E应高效q且高度<span id="wmqeeuq" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%D7%D4%B6%AF">自动</span>化?<br /> <br />   动态运行时间优化:q不是SQL 执行的每个方面都可以事先q行优化。Oracle 因此要根据当前数据库负蝲Ҏ询处理策略进行动态调整。该动态优化的目标是获得优化的执行性能Q即使每个查询可能不能够获得理想的CPU 或内存资源。Oracle 另有一个原来的优化E序Q即Z规则的优化程序。该优化E序仅向后兼容,在Oracle 的下个版本将不再得到支持。绝大多数Oracle 用户目前使用Z开销的优化程序。所有主要的应用E序供应商(如Oracle 应用E序、SAP 和PeoplesoftQ仅列出q几Ӟ以及大量q来开发的客户应用E序都用基于开销的优化程序来获得优良的执行性能Q故本文仅讲q基于开销的优化程序?<br /> <br />   SQL 语句转换 <br /> <br />   使用SQL 语句表示复杂查询可以有多U方式。提交到数据库的SQL 语句cd通常是最l用h应用E序可以最单的方式生成的SQL cd。但是这些h工编写或机器生成的查询公式不一定是执行查询最高效的SQL 语句。例如,由应用程序生成的查询通常含有一些无关紧要的条gQ这些条件可以去掉。或者,有些从某查询谓词出的附加条g应当d到该SQL 语句中。SQL 转换语句的目的是给定的SQL 语句转换成语义相同(卌回相同结果的SQL 语句Qƈ且性能更好的SQL 语句?<br /> <br />   所有的q些转换对应用程序及最l用户完全透明。SQL 语句转换在查询优化过E中自动实现?<br /> <br />   Oracle 实现了多USQL 语句转换。这些{换大概可分成两类Q?<br /> <br />   试探查询转换Q在可能的情况下对进来的SQL 语句都会q行q种转换。这U{换能够提供相同或较好的查询性能Q所以Oracle 知道实施q种转换不会降低执行性能?Z开销的查询{换:Oracle 使用Z开销的方法进行几cL询{换。借助q种ҎQ{换后的查询会与原查询相比较,然后Oracle 的优化程序从中选出最x行策略?<br /> <br />   以下部分讨论Oracle 转换技术的几个CZ。这些示例ƈ非是权威的,仅用于帮助读者理解该关键转换技术及其益处?<br /> <br />   试探查询转换 <br /> <br />   单视囑֐q?<br /> <br />   可能最单的查询转换是视囑֐q。对于包含视囄查询Q通常可以通过把视囑֮义与查询“合ƈ”来将视图从查询中L。例如,L下面的非常简单的视图及查询?<br /> <br />   CREATE VIEW TEST_VIEW AS SELECT ENAME, DNAME, SAL FROM EMP E, DEPT D WHERE E.DEPTNO = D.DEPTNO; <br />   SELECT ENAME, DNAME FROM TEST_VIEW WHERE SAL > 10000; <br /> <br />   如果不加M转换Q处理该查询的唯一Ҏ是将EMP 的所有行联接到DEPT 表的所有行Q然后筛选有适当的SAL 的值的那些行?<br /> <br />   如果使用视图合ƈQ上q查询可以{换ؓQ?<br /> <br />   SELECT ENAME, DNAME FROM EMP E, DEPT D WHERE E.DEPTNO = D.DEPTNO AND E.SAL > 10000; <br /> <br />   处理该{换后的查询时Q可以在联接EMP 和DEPT 表前使用谓词‘SAL>10000’。这一转换׃减少了联接的数据量而大大提高了查询的执行性能。即便在q样一个非常简单的CZ里,查询转换的益处和重要性也显而易见?<br /> <br />   复杂视图合ƈ <br /> <br />   许多视图合ƈ操作都是直截了当的,如以上示例。但是,较复杂的视图Q如包含GROUP BY 或DISTINCT 操作W的视图合ƈh׃那么Ҏ了。Oracle 为合q这cd杂视图提供了一些高U技术?<br /> <br />   L以下带有GROUP BY 语句的视图。在该示例中Q视图计每个部门的q_工资?<br /> <br />   CREATE VIEW AVG_SAL_VIEW AS SELECT DEPTNO, AVG(SAL) AVG_SAL_DEPT FROM EMP GROUP BY DEPTNO <br /> <br />   查询的目的是要找出Oakland 每个部门的^均工资: <br /> <br />   SELECT DEPT.NAME, AVG_SAL_DEPT FROM DEPT, AVG_SAL_VIEW WHERE DEPT.DEPTNO = AVG_SAL_VIEW.DEPTNO AND DEPT.LOC = 'OAKLAND' <br /> <br />   可以转换为: <br /> <br />   SELECT DEPT.NAME, AVG(SAL) FROM DEPT, EMP WHERE DEPT.DEPTNO = EMP.DEPTNO AND DEPT.LOC = 'OAKLAND' GROUP BY DEPT.ROWID, DEPT.NAME <br /> <br />   该特D{换的执行性能优点立即昄Q该转换把EMP 数据在分l聚合前q行联接和筛选,而不是在联接前将EMP 表的所有数据分l聚合?<br /> <br />   子查?#8220;展^” <br /> <br />   Oracle 有一些{换能不同类型的子查询{变ؓ联接、半联接或反联接。作领域内的技术示例,我们来看下面q个查询Q找出有工资过10000 的员工的那些部门Q?<br /> <br />   SELECT D.DNAME FROM DEPT D WHERE D.DEPTNO IN (SELECT E.DEPTNO FROM EMP E WHERE E.SAL > 10000) <br /> <br />   存在一pd可以优化本查询的执行计划。Oracle 会考虑q些可能的不同{换,Z开销选出最佌划?<br /> <br />   如果不进行Q何{换,q一查询的执行计划如下: <br /> <br />   OPERATION OBJECT_NAME OPTIONS <br />   SELECT STATEMENT <br />   FILTER <br />   TABLE ACCESS DEPT FULL <br />   TABLE ACCESS EMP FULL <br /> <br />   按照该执行计划,扫描DEPT 表的每一行查找所有满_查询条g的EMP 记录。通常Q这不是一U高效的执行{略。然而,查询转换可以实现效率更高的计划?<br /> <br />   该查询的可能计划之一是将查询作ؓ“半联?#8221;来执行?#8220;半联?#8221;是一U特D类型的联接Q它消除了联接中来自内表的冗余|q实际上是该子查询的原本的语义Q。在该示例中Q优化程序选择了一个散列半联接Q尽Oracle 也支持排?合ƈ以及嵌套-循环半联接: <br /> <br />   OPERATION OBJECT_NAME OPTIONS <br />   SELECT STATEMENT <br />   HASH JOIN SEMI <br />   TABLE ACCESS DEPT FULL <br />   TABLE ACCESS EMP FULL <br /> <br />   ׃SQL 没有用于半联接的直接语法Q此转换q的查询不能使用标准的SQL 来表C。但是,转换后的伪SQL 是Q?br /> <br />   SELECT DNAME FROM EMP E, DEPT D WHERE D.DEPTNO E.DEPTNO AND E.SAL > 10000; <br /> <br />   另一个可能的计划是优化程序可以决定将DEPT 表作接的内表。在q种情况下,查询作ؓ通常的联接来执行Q但对EMP 表进行特别排序,以消除冗余的部门P <br /> <br />   OPERATION OBJECT_NAME OPTIONS <br />   SELECT STATEMENT <br />   HASH JOIN <br />   SORT UNIQUE <br />   TABLE ACCESS EMP FULL <br />   TABLE ACCESS DEPT FULL <br /> <br />   转换后的SQL 语句为: <br /> <br />   SELECT D.DNAME FROM (SELECT DISTINCT DEPTNO FROM EMP) E, DEPT D WHERE E.DEPTNO = D.DEPTNO AND E.SAL > 10000; <br /> <br />   与视囑֐q一P子查询展q也是获得良好查询执行性能的基本优化办法?<br /> <br />   传递谓词生?<br /> <br />   在某些查询中Q由于表间的联接关系Q一个表中的谓词可以转化为另一个表中的谓词。Oracle 会以q种方式演绎出新的谓词,q类谓词被称Z递谓词。例如,来看一个查询,扑և定货当天q出的所有商品: <br /> <br />   SELECT COUNT(DISTINCT O_ORDERKEY) FROM ORDER, LINEITEM WHERE O_ORDERKEY = L_ORDERKEY AND O_ORDERDATE = L_SHIPDATE AND O_ORDERDATE BETWEEN '1-JAN-2002' AND '31-JAN-2002' <br /> <br />   利用传递性,该ORDER 表中的谓词也可以用于LINEITEM 表: <br /> <br />   SELECT COUNT(DISTINCT O_ORDERKEY) FROM ORDER, LINEITEM WHERE</div> <img src ="http://www.aygfsteel.com/zhuzi1987/aggbug/241551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/zhuzi1987/" target="_blank">竹子</a> 2008-11-20 09:46 <a href="http://www.aygfsteel.com/zhuzi1987/archive/2008/11/20/241551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">崨</a>| <a href="http://" target="_blank">ɿ</a>| <a href="http://" target="_blank">̨</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">żҿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ո</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">̩˳</a>| <a href="http://" target="_blank">绯</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǿ</a>| <a href="http://" target="_blank">³</a>| <a href="http://" target="_blank">ľ</a>| <a href="http://" target="_blank">ɯ</a>| <a href="http://" target="_blank">կ</a>| <a href="http://" target="_blank">κ</a>| <a href="http://" target="_blank">Ž</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">μ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ڻ</a>| <a href="http://" target="_blank">»Ȱ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank">п</a>| <a href="http://" target="_blank">ƽɽ</a>| <a href="http://" target="_blank">Ǽ</a>| <a href="http://" target="_blank">ʳ</a>| <a href="http://" target="_blank">ɽʡ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>