虎虎漫画小说

繁体版 简体版
虎虎漫画小说 > > SQL语言艺术最新章节 > 第 2 章

第 2 章 免费阅读

—本章后面还会多次涉及此问题。

总结:数据库连接和jiāo互好似万里长城——长度越长,传递消息越耗时。

战略优先于战术

Strategy

Before

Tactics

战略决定战术,反之则谬也。思考如何处理数据时,有经验的开发者不会着眼于细微步骤,而

是着眼于最终结果。要获得想要的结果,最显而易见的方法是按照业务规则规定的顺序按部就

班地处理,但这不是最有效的方法——接下来的例子将显示,刻意关注业务处理流程可能会使

我们错失最有效的解决方案。

几年前,有人给了我一个存储过程,让我“尝试”着进行一下优化。为什么说是“尝试”呢?因为

该存储过程已经被优化两次了,一次是由原开发者,另一次是由一个自称Oracle 专家的人。但

尽管如此,这个存储过程的执行仍会花上20分钟,使用者无法接受。

此存储过程的目的,是根据现有库存和各地订单,计算出总厂需要订购的原料数量。大体上,

它就是把不同数据源的几个相同的表聚合(aggregate)到一个主表(master table)中。首先,

将每个数据源的数据chā入主表;接着,对主表中的各项数据进行合计并更新;最后,将与合计

结果无关的数据从表中删除。针对每个数据源,重复执行上述步骤。所有SQL 语句都不是特

别复杂,也没有哪个单独的SQL语句特别低效。

为了理解这个存储过程,我花了大半天时间,终于发现了问题:为什么该过程要用这么多步骤

呢?在from子句中加上包含union 的子查询,就能得到所有数据源的聚合(aggregation)。一条

select 语句,只需一步就得到了结果集,而之前要通过chā入目标表(target table)得到结果集。

优化后,xìng能的提升非常惊人——从20 分钟减至20 秒;当然,之后我花了一些时间验证了

结果集,与未优化前完全相同。

想要获得上述的大幅提高xìng能,无需特别技能,仅要求站在局外思考(think outside the box)的

能力。之前两次优化因“太关注问题本身”而收到了干扰。我们需要大胆的思维,站得远一些,

试着从大局的角度看待问题。要问自己一些关键的问题:写存储过程之前,我们已有哪些数据?

我们希望存储过程返回什么结果?再辅以大胆的思维,思考这些问题的答案,就能得到一个xìng

能大幅提升的处理方式了。

总结:考虑解决方案的细节之前,先站得远一些,把握大局。

先定义问题,再解决问题

Problem

Definition

Before

Solution

一知半解是危险的。人们常在听说了新技术或特殊技术之后——有时的确很吸引人——试图采

用它作为新的解决方案。普通开发者和设计师通常会立即采纳这些新“解决方案”,直到后来才

发现它们会产生许多后续问题。

现成的解决方案中,非规范化设计引人注目。设计伊始,非规范化设计的拥护者就提出此方案,

为了寻求“xìng能”而无视最终将会面临的升级恶魔——而事实上,在开发周期早期,改进设计(或

学习如何使用join)也是一个不错的选择。作为非规范化设计的一种手段,物化视图(materialized

view)常被认为是灵丹妙yào。物化视图有时被称为快照(snapshot),这个更加平常的词更形象

地反映了可悲的事实:物化视图是某时间点的数据副本。在没有其他办法时,这个理论上遭到

质疑的技术也未尝不值得一试,借用卡夫卡(Franz Kafka)的一句名言:“逻辑诚可贵,生存价

更高。”

然而,绝大部分问题都可借助传统技术巧妙解决。首先,应学会充分利用简单、传统的技术。

只有完全掌握了这些技术,才能正确评价它们的局限xìng,最终发现它相当于新技术的潜在优势

(如果有的话)。

所有技术方案,都只是我们达到目标的手段。没有经验的开发者误把新技术本身当成了目标。

对于热衷于技术、过于看重技术的人来说,此问题就更为严重。

总结:先打基础,再赶时髦:摆弄新工具之前,先把手艺学好。

直接cāo作实际数据

Operations

Against

Actual

Data

许多开发者喜欢建立临时工作表(temporary work table),把后续处理使用的大量数据放入其中,

然后开始“正式”工作。这种方法广受质疑,反映了“跳出业务流程细节考虑问题”的能力不足。

记住,永久表(permanent table)可以设置非常复杂的存储选项(在第5章将讨论一些存储选项

的设置),而临时表不能。临时表的索引(如果有的话)可能不是最优的,因此,查询临时表的

语句效率比永久表的差。另外,查询之前必然先为临时表填入数据,这自然也多了一笔额外的

开销。

就算使用临时表有充足理由,若数据量大,也绝不能把永久表当作临时工作表来用。问题之一

在于统计信息的自动收集:若没有实时收集要求,DBMS通常会在不活动或活动少时进行统计

信息收集,而这时作为临时工作表可能为空,从而使优化器收到了完全错误的信息。这些不正

确且有偏差的统计信息可能造成执行计划(execution plan)完全不合理,导致xìng能下降。所以,

如果一定要用临时表,应确保数据库知道哪些表是临时的。

总结:暂时工作表意味着以不太合理的方式存储更多信息。

用SQL

处理集合

Set

Processing

in

SQL

SQL 完全基于集合(Set)来处理数据。对大部分更新或删除cāo作而言—— 如果不是针对整

个表的话—— 你必须先精确定义出要处理的记录的集合。这定义了该处理的粒度

(granularity),可能是对大量记录的粗粒度cāo作,有可能是只影响少数记录的细粒度cāo作。

将一次“大批量数据的处理”分割成多次“小块处理”是个坏主意,除非对数据库的修改太昂贵,

否则不要使用,因为这种方法极其低效:

(1)占用过多的空间保存原始数据,以备事务(transaction)回滚(rollback)之需;

(2)万一修改失败,回滚消耗过长的实践。

许多人认为,进行大规模修改cāo作时,应在cāo作数据的代码中有规律地多安排些commit命令。

其实,严格从实践角度来讲,“从头开始重做”比“确定失败发生的时间和位置,接着已提jiāo部分

重做”要容易得多、简单得多、也快得多。

处理数据时,应适应数据库的物理实现。考虑事务失败时回滚所需日志的大小,如果要为undo

保存的数据量确实巨大,或许应该考虑数据修改的频率问题。也就是说,将大规模的“每月更新”,

改为规模不大的“每

松语文学免费小说阅读_www.16sy.com

『加入书签,方便阅读』