`
Supanccy2013
  • 浏览: 213753 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

sql语句执行顺序

阅读更多
一,select语句执行流程
   FROM:对FROM子句中前两个表执行笛卡尔积生成虚拟表vt1
   ON:对vt1表应用ON筛选器只有满足< join_condition> 为真的行才被插入vt2
   OUTER(join):如果指定了 OUTER JOIN保留表(preserved table)中未找到的行将行作为外部  
   行添加到vt2 生成t3如果from包含两个以上表则对上一个联结生成的结果表和下一个表重复执 
   行步骤和步骤直接结束
   WHERE:对vt3应用 WHERE 筛选器只有使< where_condition> 为true的行才被插入vt4
   GROUP BY:按GROUP BY子句中的列列表对vt4中的行分组生成vt5
   CUBE|ROLLUP:把超组(supergroups)插入vt6 生成vt6
   HAVING:对vt6应用HAVING筛选器只有使< having_condition> 为true的组才插入vt7
   SELECT:处理select列表产生vt8
   DISTINCT:将重复的行从vt8中去除产生vt9
   ORDER BY:将vt9的行按order by子句中的列列表排序生成一个游标vc10
   TOP:从vc10的开始处选择指定数量或比例的行生成vt11 并返回调用者
二:sql优化
1,避免不恰当的使用“SELECT *”
   如果 SQL 语句使用了“SELECT *”,DB2 就需要把表的所有列都从外部存储介质上(如磁带或者硬盘)复制到 DB2 的内存中来进行处理并且返回给用户,这显然会增加 I/O 和 CPU 的开销。而且如果这条 SQL 语句还包括了排序(Sort)操作(比如 ORDER BY),那么对全部这些列进行排序也可能会影响到性能。而且当表定义的列越多,每个列定义的数据类型(Data type)长度越长,这对性能的影响就可能越明显。

2,避免在本地谓词的列上使用复杂表达式(会导致该列的索引失效)
  YEAR(Date) > 2004 和 Amount > 1000 都是两个本地谓词。然而在前一个谓词 YEAR(Date) > 2004 中,它对 Date 这个列有一个函数 YEAR 的调用。在这种情况下,即使 Date 上存在一个索引,DB2 也无法使用这个索引来访问数据。如果能够在确保语义不变的前提下,适当改写这个谓词,避免在 Date 列上调用函数,那么情况可能会有所不同。例如,这个谓词可以改写为如下的样子
   实例:
    SQL 1:select l_quantity, l_comment from lineitem
           where l_orderkey + 100 = 200
    SQL 2:select l_quantity, l_comment from lineitem
           where l_orderkey = 100
    解析:sql1会导致l_orderkey列上的索引失效。sql2则不会。所以正确的写法为sql2.

3,避免用复杂表达式构建连接谓词
    Select T1.C1 From T1, T2 Where T1.C1 * T1.C2 = T2.C2
    在连接谓词 T1.C1 * T1.C2 = T2.C2 中,“=”左边不是一个列名,而是一个表达式,它涉及 T1 表上不同列之间的计算。对于这样一个用复杂表达式构建的连接谓词,DB2 只能用 Nested-Loop-Join 这种最基本的方式来建立 T1 和 T2 之间的连接,而不考虑用其他的连接方式,从而也就无法选择最优的连接方式。所以这种在连接谓词中使用复杂表达式的写法不是一个好的习惯,在写 SQL 语句时应该注意避免。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics