首页>参考读物>计算机科学与技术>综合

SQL应用重构
作者 : (美)Stéphane Faroult 等著
译者 : 苏敬凯 译
出版日期 : 2009-11-18
ISBN : 978-7-111-26358-6
定价 : 49.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 296
开本 : 16
原书名 : Refactoring SQL Applications
原出版社:
属性分类: 店面
包含CD :
绝版 : 未绝版
图书简介

在本书中你将学习:
  判断你是否(以及在哪里)可以得到性能的提升
  应用快速修复的方法,例如在存储函数和过程中限制对数据库的调用
  改写SQL语句以提高数据访问的效率
  重构任务,例如用存储过程代替应用代码,用SQL语句代替重复的过程化语句
  增加并行以重构流程
  使用模式扩展、常规视图、物化视图、分区等来重构设计

图书前言

我写书的目的是让它对于能理解它的人有用,因此,我更应当去探究问题的真相,而不是想当然。
—— 尼可罗·马基亚维利
《君主论》 第15章
  在本书的背后有一个故事。那时我刚刚写完《The Art of SQL》,该书还没有开始销售,该书的编辑Jonathan Gennick就产生了让我写一本关于SQL重构的书的想法。我知道SQL,但从未听过SQL重构。于是,我Google了一下这个词,在莫里哀的名剧《贵人迷》中,茹尔丹先生(Monsieur Jourdain),一位富有但没受过良好教育的男子,在他成年以后才开始上一些课程,他惊讶地发现原来他一辈子一直都在说“散文”。就像茹尔丹先生那样,我发现多年来我一直在重构SQL代码,却不知道这个词 —— 对客户的系统进行性能分析会非常自然地引发“通过增量的小改动来改进代码同时又不改变程序”的行为。重构SQL应用就是:尽你所能设计出一个好数据库来,并对架构和程序进行合理布局以使对数据库的访问更加高效。另一个问题就是:你所面对的系统未必是一个刚开始设计的系统,它可能已经运行了若干年,一切都已超出了控制而你却还必须要使用它,那么如何能使这些系统的性能达到最佳呢。以这样一个在我的职业生涯中经常出现的视角来展现SQL语言,这种想法确实有些吸引力。
  在写完一本书之后,最不想做的事情就是再写另一本书。但这个想法却一下子抓住了我的心。我曾和几个朋友讨论过这一想法,其中一个人是我所认识的最令人敬畏的SQL专家。这个朋友爆发了,这些时髦词汇使他义愤填膺。不过,这一次我不能同意他的意见了。确实,这一首先由Martin Fowler(注1)普及开来的“通过小得几乎微不足道的局部修改来改进代码”的想法看起来就像一种时尚 —— 完全是由那些刚刚从大学毕业的企业顾问们用报告堆积出来的时尚。但对于我来说,重构的真正意义不仅在于“我们不再把那些已投入生产的代码视作是神圣不可侵犯的”,还在于我们认识到“只要经过一点努力,很多表现平庸的系统就能够表现得好很多”。重构还是一种认可,承认“性能不令人满意的错误在于我们自己,而不在于我们的运气”,这也确实是业界的一个启示。
  在很多地方我都看到,IT经理们对于性能有着一种几乎悲观的态度,人们感觉是受着命运的折磨,他们把最后的一点希望放在“调优”上。如果数据库和系统管理员的努力失败了,在他们看来,唯一的选择就只能是签发订单采购性能更高的硬件了。我也读到过很多自称是数据库专家的人所写的审计报告,在将系统工具的输出重新编排了一下格式之后,他们就得出了“需要提高某几个参数”以及“应该增加更多内存”的结论。公平地说,有些报告中也提到了应该对一些糟糕的查询进行“调优”,但除了把SQL语句的执行计划贴在附录里之外,没有更明确地说明如何调优。
  我已经很多年没有碰过数据库的参数了(客户的技术团队通常很称职)。不过,我改进了很多程序,毫无畏惧地研究它们,我尽可能和开发人员一起工作,而不是呆在我的象牙塔里从很远的地方发号施令。我几乎总是遇到渴望学习和理解的人、几乎不需要鼓励就能走上正确道路的人、喜欢学习SQL技能的人以及能很快开始为自己设定性能目标的人。
  当流逝的时光将写书的痛苦从我的记忆中抹去之后,我做出了果断的决定,又一次开始了写作,因为我打算扩展这些在我与开发人员一起工作时想要传达给他们的思想。数据库访问可能是能从代码改进中获益最多的区域之一。我写本书的目的不是给出一些具体的做法,而是给出一个框架,以此来改进我们周围那些不够理想的SQL应用,而不用从头开始重写它们(尽管有时重写会有非常强的诱惑力)。
为什么重构
  大多数的应用迟早都会遇到性能问题。最好的情况是,一些辉煌的应用系统曾经是成功的,随着时间的推移,它们要处理的数据量已达到了设计时根本想不到的程度。因此,这些旧程序需要重生,直到在生产环境中投入了一个新的应用系统来替代它为止。最坏的情况是,在产品上线之前所进行的性能测试中,就发现性能不能满足服务水平要求。而介乎于最好与最坏之间的情况是,数据量增长、增加新功能、软件升级或配置变更都时常能揭示出一些一直隐藏着的瑕疵,而又不是永远都可以选择回溯。所有这些情况都有极其苛刻的性能改进截止期限和很高的压力。
  首先到达的救援队通常都是系统工程师和数据库管理员,他们被请来表演神奇的参数舞蹈。除非之前没有注意到某些非常大的错误(这确实发生过),对于系统性能的提升来说,数据库和系统调优的帮助通常很有限。
  这时,下一步的传统做法一直就是:为应用系统中投入更多的硬件。这是一个成本非常高的选择,因为硬件的价格中可能还包含了更高的软件许可成本。这样做还会中断业务的运行,并且必须为此制订计划。令人担忧的是,无法真正保证这一投资能有所回报。很多大型硬件升级后都没有达到预期效果,这种情况不止一次地发生过。似乎与我们的直觉相反,很多大型硬件升级的恐怖故事实际上是:硬件升级反而导致了性能的退化。在很多情况下,在一台机器里多加几个处理器也只不过是进一步加剧了进程之间的争夺而已。
  重构的概念引入了一个在调优和大型硬件投入之间的急需的中间状态。在Martin Fowler的那部关于重构的有创意的著作中,他所关注的是面向对象技术。但是数据库所处的情景与用对象语言或过程语言编写的应用程序有着明显的差异,而这些差异也带来了一些对于重构工作的特殊的曲解。例如:
小改动有时不那么小
  由于SQL语言的描述式的本质,对于代码的小改动往往给在SQL引擎中的执行带来巨大的影响,这也就会导致性能上的巨大变化 —— 可能更好也可能更差。
对改动的有效性进行测试可能很困难
  检查返回一个值的函数非常简单,只要检查在各种情况下代码修改前后的返回值是否相同就行了。而在改写了一个主要的update语句后,要检查一个大表的内容是否保持相同,这完全是另外一回事。
上下文环境往往是决定性的
  在问题出现前的若干年里,数据库应用系统可能一直运行得非常令人满意;但在数据量或负载超过了某些阈值之后,或者在一次软件升级改变了优化器的行为之后,性能往往会突然变得无法让人接受。对于数据库应用系统的性能改进工作通常就发生在一场危机当中。
  因此,数据库应用系统是重构的一个完全不同的战场,而同时这种努力也可能是(往往也就是)有高额回报的。
数据库访问的重构
  长时间以来,数据库专家们都知道,提升性能最有效的方式是:先检查索引,再评审和细调访问数据库的模式。虽然表面上SQL语言有着描述式的本质,但这一语言还有这样的恶名:功能完全相同的语句可以有不同写法,而有时不同的写法在执行时间上有着令人吃惊的差别。
  然而,数据库访问的重构不仅仅是改写有问题的查询语句,但大多数人却都止步于此了。例如,经过SQL语言若干年来缓慢但持续的改进,有时开发人员可以编写一些高效率的语句来替代以前的含有多条语句的复杂过程,也能完成同样的功能。很多新内置到数据库引擎中的机制能够让你以一种与过去不同的方式来更高效地做事。按照(数据库的)新特性来检查旧程序往往能产生大幅度的性能提升。
  如果重构背后的原因只是期望利用新特性使旧应用程序返老还童,那么这真的是一个美丽新世界。对于那些被我策略地称为“不够优化”的代码来说,数据库应用系统的正确解决办法也能够创造奇迹。
  修改应用系统的逻辑结构,似乎与前面所说的“保持较小变更”的目标相矛盾。实际上,你对于“小和增量意味着什么”的理解取决于你的阅历;当你第一次到一个没去过的地方时,路似乎总是很长,而当你再次回到这个地方,成为常客以致于熟悉这里时,路似乎就没那么长了。
我们可以期待从重构中得到什么
  重要的是要理解,主要控制着重构效果的是下面这两个因素(实际上,它们是相互矛盾的因素):
   首先,重构的收益与最初的应用系统有着直接的关系:如果代码的质量很差,那么一次成功的改进就很有可能唾手可得。如果代码非常理想,那么可能就没有什么重构的机会 —— 引入新特性除外,这也可能就是故事结束的时候了。就像公司一样,只有管理糟糕的公司才能被神奇地扭转。
   其次,如果数据库设计得真的很糟糕,那么重构也不会有太大效果。事情只能变得略微不那么糟糕,但决不会产生令人满意的结果。重构是一个渐进的过程。在数据库这一特定情形下,如果没有最初的明智设计,即便是明智的演变过程也无法使应用系统适于生存。这样的应用系统必将崩溃并绝迹。
  像伟大的拉丁诗人贺拉斯那样,在把《aurea mediocritas》(即golden mediocrity,中庸是金)写出来之前,先把它在脑海里重构一遍,是不可能的。但对于一些平凡的应用系统来说,我们确实可以对重构寄予最好的愿望。这样的应用系统有很多,因为正如本书的评论者Roy Owens说的那样“如果第一种每个人都同意的方式在功能上可以工作,那么它也就变成了设计”,这种情况太常见了。
本书的组织方式
  本书尽量以一种现实和诚实的眼光来看待那些在SQL起重要作用的应用系统中的改进工作,并且详细描述了一个可用于战术演习的合理框架。往往是在疯狂追求“快速取胜”和“显著改进”的时候,才会进行重构,因为这样能防止预算被削减,能保住肩膀上的脑袋。严格地说,在普遍恐慌时,保持头脑冷静并采取系统化的方法才最有作用。让我们提前申明一下:奇迹,根据它的定义,是少数极有天赋的人的领地,它们通常适用于比你的应用系统更有价值的理由(无论你怎么理解这句话)。而理由充分地系统化应用一些合理原则反而更能取得引人注目的结果。本书将尽力帮你明确不同的策略,评估不同解决方案的可行性以及评估对于增量一词的不同解释所带来的风险。
  在很多情况下,SQL应用系统的重构工作都会按照一种与开发相反的顺序来进行:从容易的事情开始,逐渐深入地切入,直到你到了一种会有所损害的程度或你已达到了自愿设置的限制时为止。在本书中,我也尽量遵照同样的顺序来组织内容。
第1章“评估”
  这一章是开场白,它讲述的是如何对形势进行评估。重构通常都与需要仔细分配的稀缺资源有关。因此没有犯错和对错误的目标进行改进的余地。该章将指引你评估的是:1)是否有希望进行重构;2)你有理由抱有哪种希望。
  接下来的两章将讨论每个经理的梦想:快速取胜。在这两章中,我讨论的是主要发生在数据库一侧的修改,而不是应用程序一侧的修改。有时,你甚至还可以把其中一些修改用于你没有权限访问其源代码的“罐头式的应用系统”中。
第2章“健全检查”
  讨论那些必须按照优先级进行控制的要点 —— 特别是对索引的评审。
第3章“用户函数和视图”
  解释为何大量使用用户编写的函数和视图有时会使应用系统的性能大大降低,以及怎样能使它们对性能的影响最小化。
  在接下来的三章中,我将讲述可以对应用系统做哪些修改。
第4章“测试框架”
  讲解如何组建一个正确的测试框架。在修改代码时,要确保我们仍然能够得到相同的结果,这一点很关键,因为任何一处修改,无论它多么小,都可能引入缺陷;没有任何一处修改是完全无风险的。该章将讨论比较一个程序的前后两种版本的策略。
第5章“语句重构”
  深入讨论编写各种SQL语句的正确方法。优化器会改写次优(即未达最佳标准的)语句,这是优化器应当做的事情。但是,最精明的优化器也只能尽量利用现有的情况。我将向你展示如何分析并改写SQL语句,从而将优化器变为你的朋友,而不是你的对手。
第6章“任务重构”
  将第5章的讨论进一步推向深入,解释操作模式的修改 —— 特别是去除以记录为基础的处理方式 —— 如何能把我们带入一个更高的层次。通常,改写单个语句所产生的结果仅仅是潜在改进成果中很小的一部分。应该更大胆地向前走,比如将几个语句联合起来,或者用气势磅礴的SQL语句来替代循环的过程化的语句,这些做法常常会取得令人惊喜的收获。这些收获要求有很好的SQL技能,而SQL的理念与传统的过程化理念及面向对象的理念非常不同。我将介绍一些这样的例子。
  到了这个阶段,如果你仍然对性能不满意,那么你最后的希望就在下一章中。
第7章“重构流程和数据库”
  回到数据库上来,讨论一些更底层的修改。首先,我将讨论如何通过改变流程和引入并行来提升性能,展示在将处理并行化以后需要注意的一些新问题,比如数据一致性、竞争和加锁。然后,我将讨论最后一招:有时可以对数据库结构进行物理上和逻辑上的修改,从而获得一些额外的性能提升。
  接下来是对本书的总结。
第8章“实践中的重构”
  这一章是对全书的总结,提供了一个扩展的检查列表。在该章中,我将引用前面的章节来描述:当我必须处理数据库应用系统的性能问题时,我的脑海里想的是什么,我做的是什么。这对于我是个难题,因为经验(以及通过经验获取的直觉)所建议的快捷方法有时没有真正经过清晰思考并且合乎逻辑的分析,但我还是希望它能成为一个有用的参考。
  附录A“脚本及样例程序”和附录B“工具”。
  描述了脚本、样例程序和工具,这些都可以从O誖eilly上本书的网页中下载:
  http://www.oreilly.com/catalog/9780596514976。
读者对象
  本书为IT专业人士、开发人员、项目经理、维护团队、数据库管理员及调优专家而写,他们可能会参与到对一个数据库组件占很重要作用的应用系统进行的拯救活动中。
阅读本书的前提
  本书假设读者有很好的SQL语言知识,当然,至少熟悉一种编程语言会更便于理解本书。
本书排版约定
  本书使用如下的排版约定:
  斜体(Italic)
  表明是需要强调的部分、新术语、URL、文件名和文件扩展名。
  等宽字体(Constant width)
  表明是广义的计算机代码,包括命令、选项、变量、属性、键、请求、函数、方法、类型、类、模块、对象属性、参数、值、对象、事件、事件处理程序、XML和XHTML标签、宏及关键字。它也会用来表示表名、字段名之类的标识符,还用来表示代码样本和命令输出结果。
  等宽粗体(Constant width bold)
  表明是代码样本中需要强调的部分。
  等宽斜体(Constant width italic)
  表示这部分文本应当被替换为用户提供的具体值。
源代码例子的使用
  本书的目的是为了帮助你完成工作。总的来说,你可以在自己的程序和文档中使用本书中的这些源代码。你不需要联系我们以获得许可,除非你要复制这些代码中的很大一部分。例如,在编写一个程序时使用本书中的几段代码,不需要许可。销售或分发O誖eilly图书所带的例子CD-ROM,不需要许可。在回答问题时引用本书或引用例子代码,不需要许可。在你的产品文档中采用本书中很大一部分示例代码,需要许可。
  我们感谢注明出处,但并不要求必须这样做。在注明出处时,通常应包括标题、作者、出版商和ISBN号。例如“Refactoring SQL Applications by St巔hane Faroult with Pascal L誋ermite. Copyright 2008 St巔hane Faroult and Pascal L誋ermite, 978-0-596-51497-6”。
  如果你感觉自己对于代码例子的使用已超出了这里给出的许可范围,就请联系我们,邮件地址为permissions@oreilly.com。
如何联系我们
  关于本书的评论和疑问都可以发送给出版社:
  美国:
  O'illy Media, Inc.
  1005 Gravenstein Highway North
  Sebastopol, CA 95472
  中国:
  北京市西城区西直门南大街2号成铭大厦C座807室(100035)
  奥莱利技术咨询(北京)有限公司
  我们为本书建立了一个网页,上面列出了勘误表、例子和一些额外的信息。你可以用如下地址来访问它:
  http://www.oreilly.com/catalog/9780596514976(英文版)
  http://www.oreilly.com.cn/book.php bn=978-7-111-26358-6(中文版)
  评论本书或者提一些关于本书的技术问题,请发电子邮件至:
  bookquestions@oreilly.com
  在我们的网站上有更多的关于我们的图书、会议、资源中心和O誖eilly网络的信息,欢迎访问:
  http://www.oreilly.com
  http://www.oreilly.com.cn
致谢
  一本书的写作是很多人工作的成果,不止是名字印在封面上的那些人。首先,我要感谢Pascal L誋ermite,他的Oracle和SQL Server的知识在我写本书时极有价值。在一本技术书籍中,文字只是一切努力中可见的那一部分。设置测试环境,设计样例程序,将它们移植到各种数据库平台上,有时还要尝试一些最终不会有什么结果的想法,所有这些任务都要花很长时间。在本书的背后有很多看不见的工作,很多的工作在最终成书时都只是表现为一些看似随意的引用和模糊的影子。没有Pascal的帮助,本书可能要花更长的时间才能写完。
  每个项目都需要经理人,而我的编辑Mary Treseler就是O誖eilly出版社的项目经理。Mary选择了一个非常好的评审团队,其中的几个人也是作家。首先要感谢的是Brand Hunt,他是本书的技术编辑。我衷心地感谢Brand,他帮助我对本书进行了最终的定型。还要感谢Dwayne King,特别感谢他修改本书的行文及代码。David Noor、Roy Owens和Michael Blaha也非常有帮助。我还要感谢两位专家,同时也是我的老朋友:Philippe Bertolino和Cyril Thankappan,他们也仔细地评审了本书的草稿。
  除了纠正了一些错误之外,这些评审者都贡献了自己对于最终产品的评论和说明,这使本书变得更好。
  在作者和评审者的工作完成之后,很多O誖eilly人的工作才开始:在制作编辑的领导下,他们对本书进行编辑加工,书籍设计,封面设计,将我那些难看的图表改成更符合O誖eilly标准的东西,为本书建立索引,所有这些都有助于本书的最后面世。我由衷地感谢Rachel Monaghan、Audrey Doyle、Mark Paglietti、Karen Montgomery、Marcia Friedman、Rob Romano和Lucie Haskins。

封底文字

当数据库的性能达不到预期时,该怎么办呢?在转而用昂贵的硬件升级的办法来解决这一问题之前,请拿起这本书。本书将教你如何发现和评估需要重构的代码,理解重构和性能之间至关重要的关系。如果你的应用陷入了困境,那么本书将能帮你使它重新加快速度。
在本书中你将学习:
  判断你是否(以及在哪里)可以得到性能的提升
  应用快速修复的方法,例如在存储函数和过程中限制对数据库的调用
  改写SQL语句以提高数据访问的效率
  重构任务,例如用存储过程代替应用代码,用SQL语句代替重复的过程化语句
  增加并行以重构流程
  使用模式扩展、常规视图、物化视图、分区等来重构设计

“有很多讲述程序重构的书,但一直缺少讲述数据库代码重构的书,直到本书出版为止。在Stéphane Faroult的这本新书中有很多高级的SQL技术,我一直在自己的工作中使用这些技术。我热情地向大家推荐这本书。”
——Michael Blaha,咨询师,OMT Associates Inc.
“终于有了这样一本书,它强调了SQL编写者在数据库总体性能上的作用,以及怎么来改进这一情形。对于任何一位数据库专业人士来说,只要你想要提升自己的查询编写能力,或者想要改进别人写的查询,那么本书就是你的必读之书。”
——Dwayne King,总裁,KRIDAN Consulting
“本书装满了宝贝。在放下本书之前,你一定会体验到惊喜。在本书中,Faroult先生慷慨地分享了他的那些意味深长的经历和清晰的思维。”
——Roy Owens,数据库开发人员,CBORD Group, Inc.

作者简介:
Séphatne Faroult从1983年开始接触关系数据库和SQL语言 ,他从事数据库咨询工作已经20多年了。O'Reilly的《SQL语言艺术》也是他的作品。
Pascal L'Hermite一直从事各种环境下的关系数据库的工作,包括OLTP环境,生产环境和开发环境,其中使用Oracle数据库12年,使用SQL Server数据库5年。

作者简介

(美)Stéphane Faroult 等著:暂无简介

译者简介

苏敬凯 译:暂无简介

译者序

译者序
  在翻译本书时,正流行着几本名为“啥啥之美”的书。本书也可以说讲的就是“如何将SQL写得更美”。
  SQL之美就在于用清楚合理的方式告诉DBMS你要做什么,让DBMS总能以最优的方式高效地完成任务。SQL是一种描述式语言,在描述中要表达清楚能够影响优化器决策的要点,同时避免过程化思维的那些细节。而要做到这一点,理解优化器的工作方式和SQL的理念至关重要,正如某条广告语讲的那样“知其道,用其妙”。
  本书作者从事数据库咨询工作多年,在本书中,不仅举出了很多具体生动的例子,还讲述了很多重构SQL应用的思想。无论你是DBA还是程序员,本书都能帮你写出或改写(也就是重构)出优美的SQL语句、清楚明了的处理过程,从而交付出高效的系统,赢得众人的赞许,就像书中的很多故事那样。
  参加本书翻译的还有赵龙刚、金振林、周志强、杨宁等。本书翻译力求忠于原著,但由于时间仓促,译者水平有限,翻译错误和不妥之处在所难免,欢迎广大读者批评指正。
苏敬凯
2008年12月

图书目录

前言 1
第1章 评估 11
一个简单的例子 12
评估可能的收益 30
第2章 健全检查 47
统计信息与数据失真 48
检查索引 54
解析与绑定变量 65
大数据量操作 82
事务管理 84
第3章 用户函数和视图 87
用户自定义函数 88
视图 116
第4章 测试框架 127
生成测试数据 127
比较备选版本 144
第5章 语句重构 159
执行计划和优化器指示 160
分析缓慢查询 165
重构查询核心 170
重新构建最初的查询 189
第6章 任务重构 193
SQL的理念 194
更改代码结构 199
第7章 重构流程和数据库 227
重组处理过程 228
撼动基础 250
第8章 实践中的重构 261
你能看到数据库吗 261
失败的查询 263
速度很快的查询 265
并非显然完全错误的查询 266
结束语 267
附录A 脚本及样例程序 269
附录B 工具 279

教学资源推荐
作者: 郭晓平 朱鸣华 编著
作者: (加)Simon Haykin 著
作者: 徐明星 编著
作者: 吴跃 主编 李树全 尚明生 陈端兵 参编