现在的位置: 首页 > 综合 > 正文

sql优化-典型案例

2013年09月18日 ⁄ 综合 ⁄ 共 1478字 ⁄ 字号 评论关闭

    今天写了个sql,为了验证下不同sql写法性能上有何区别,我专门用了两种实现方式,结果发现差别还蛮大的。

    需求:查询出口额在前十大的企业信息。

    实现方式一:

SELECT A.V_COCODE    ,
       A.COMPANY     ,
       A.TOTALDOLLAR 
  FROM (SELECT T1.V_COCODE,
               T1.COMPANY,
               SUM(T.EXPORTSUM) TOTALDOLLAR,
               ROW_NUMBER() OVER(ORDER BY SUM(T.EXPORTSUM) DESC) ROWNO
          FROM F_CUSTOM_EXPORTDETAIL T, D_CUSTOM_COMPANY T1
         WHERE T.COCODE = T1.COCODE
           AND T.MONTHID BETWEEN 201201 AND 201301
           AND T.YEARID BETWEEN 2012 AND 2013
         GROUP BY T1.V_COCODE, T1.COMPANY) A
 WHERE A.ROWNO <= 10

    该方式是将企业维表与明细表进行关联后,然后用group by进行汇总,最后再筛选出前十大企业。

实现方式二:

SELECT B.V_COCODE    海关企业编码,
       B.COMPANY     海关企业名称,
       A.TOTALDOLLAR 出口额
  FROM (SELECT T.COCODE,
               SUM(T.EXPORTSUM) TOTALDOLLAR,
               ROW_NUMBER() OVER(ORDER BY SUM(T.EXPORTSUM) DESC) ROWNO
          FROM F_CUSTOM_EXPORTDETAIL T
         WHERE T.MONTHID BETWEEN 201201 AND 201301
           AND T.YEARID BETWEEN 2012 AND 2013
         GROUP BY T.COCODE) A,
       D_CUSTOM_COMPANY B
 WHERE A.COCODE = B.COCODE
   AND A.ROWNO <= 10

    该方式是将明细表中数据按企业id进行group by汇总后,然后筛选出10大企业(优化器处理)后关联企业维表。

    在我的工作机上,方式一执行时间为2‘29,方式二执行时间为0’56,很明显方式二效率更高。

    这是为什么呢?先用执行计划验证上面的结论:

    方式一执行计划:

    方式二执行计划:

    可以看出,方式一比方式二开销更大。

    看执行计划也可以看出,遍历这两个表所花的时间一样,主要区别就在于group by,方式一的两个表先进行关联,然后在group by,开销明显更大。

    因此,group by的时候,关联的表越少越好。(这里有个前提:访问detail表中的结果集较大时,我们应该这么做。但如果增加一个过滤条件,使结果集较少,那么多表进行关联,性能未必差,因为基于成本的优化器会帮我们选择最佳的执行路径。

 

    另外,因为F_CUSTOM_EXPORTDETAIL是按年分区的分区表,所以在查询某个月份的数据时,必须要指出相应的年份,否则数据库在查询时,不会根据分区进行查找,这样速度会相当慢。

    上面的例子只是对企业这个维度进行了汇总,而且企业是有维表的,所以这么处理可以提高性能。如果要按企业、省份来汇总,如此处理就会有问题。因为detail表中没有省份信息,必须通过地区找到对应的省份,所以无法先按省份汇总,然后再到省份维表中查找对应省份。如果要按上面的处理方式,就需要两层group by,这样性能反倒会降低很多。

    因此,基本上可以得到一个结论:如果只用一次group by能搞定的,就只用一次group by,并且group by过程中关联的表越少越好。当然,具体情况还需要具体分析。

抱歉!评论已关闭.