字体
第(4/6)页
关灯
   存书签 书架管理 返回目录
rcapp 187759

    tstg 702403

    认真研究表及表的关联情况,得到图6-2所示的分析图:小箭头代表较弱的选择条件,方块为表,

    方块的大小代表记录数多少。注意:在中心位置的tTRaoma表,几乎和其他所有表有关联关系,

    但很不幸,选择条件都不在tTRaoma表。另一个有趣的事实是:上述的查询语句中,我们必须

    提供TRgppdt表的risktyp字段和riskflg字段的值作为条件——为了连接(join)TRgppdt表和tpdt

    表要使用这两个字段和pdtcod 字段。在这种情况下,应该思考倒转此流程——例如把tpdt表的

    字段与所提供的常数做比较,然后只从trgppdt表取得数据。

    图6-2:数据的位置关系

    多数DBMS提供“检查优化器选择的执行计划”这一功能,比如通过explain命令直接检查内存中

    执行的项目。上述查询花了25 秒(虽然不是特别糟),通常是先完整扫描tTRaoma表,接着进

    行一连串的嵌套循环,使用了各种高效的索引(详述这些索引

    很乏味,我们假设所有字段都建立了合适的索引)。速度慢的原因是完整扫描吗?当然不是。为

    了证明完整扫描所花时间占的比例甚微,只需做如下简单的测试:读取tTRaoma表的所有记录;

    为了避免受到字符显示时间的干扰,这些记录无需显示。

    优化器发现:tstg表有“大量敌军”,而查询中针对此表的选择条件比较弱,所以难以对它形成“正

    面攻击”;而ttrcapp表在查询的from子句中出现两次,但基于该表的判断条件也较弱,所以也不

    会带来查询效率的提升;但是,ttraoma表的位置显然很关键,且该表比较小,适合作为“第一攻

    击点”——优化器会毫不犹豫地这么做。

    那么,既然对tTRaoma表的完整扫描无可厚非,优化器到底错在哪里呢?请看图6-3所示的查询

    执行情况。

    图6-3:优化器选择的执行路径

    注意观察图中所示的cāo作执行顺序,查询速度慢的原因显露无遗:我们的查询条件很糟糕,优

    化器选择完全忽略它们。优化器决定先对ttraoma表进行完整扫描;接着,访问和表ttraoma关联

    的所有小型表;最后,对其他表运用我们的过滤条件。这样执行是错误的:虽然优化器决定首

    先访问表ttraoma有道理(该表的索引可能非常高效,每个键平均对应的记录数较少,或者索引

    与记录的顺序有较好的对应关系),但将我们提供的查询条件推迟执行,不利于减少要处理的数

    据量。

    既然已访问了ttraoma这个关键表,应该紧接着执行语句中的查询条件,这样可以借助这些表与

    ttraoma表之间的连接(join)先去除ttraoma表中无用的记录——甚至在结果集更大时,如此执

    行的效率仍比较高。但是上述信息我们知道,“优化器”却无从知道。

    怎样才能迫使DBMS 依我们所要求的方式执行查询呢?要依靠SQL 方言(SQL dialect)。正如

    你将在第11章看到的,多数SQL 方言都支持针对优化器的指示或提示(hint),虽然各种方言

    所用语法不同;例如,告诉优化器按表名在from 子句中
上一页 目录 下一页