这两个查询的性能比较

Posted

技术标签:

【中文标题】这两个查询的性能比较【英文标题】:Performance comparison of these two queries 【发布时间】:2014-04-08 10:10:14 【问题描述】:

我正在使用此查询来获取结果,其中Calander(主键:DAY_DATE)包含有关时间的所有连续信息(即日期、季度、年份等),EXPENCEINCOME 都有列TXN_DATE 作为DAY_DATE 的外键。

  SELECT
    COALESCE(t1."FISCAL_YEAR",t2."FISCAL_YEAR") "FISCAL_YEAR" ,
    "exp" "exp" ,
    "rev" "rev" 
    FROM
    (SELECT
    Calander.FISCAL_YEAR "FISCAL_YEAR" ,
    (SUM("EXPENCE"."TXN_AMT" )) "exp" 
    FROM
        Calander ,
        EXPENCE 
    WHERE
        "EXPENCE"."TXN_DATE"="Calander"."DAY_DATE" 
    GROUP BY 
        FISCAL_YEAR ) t1 FULL OUTER JOIN (SELECT
        Calander.FISCAL_YEAR "FISCAL_YEAR" ,
        (SUM("INCOME"."TXN_AMT" )) "rev" 
    FROM
        Calander ,
        INCOME 
    WHERE
        "INCOME"."TXN_DATE"="Calander"."DAY_DATE" 
    GROUP BY 
        FISCAL_YEAR ) t2 ON 
        t1."FISCAL_YEAR"=t2."FISCAL_YEAR"  
    ORDER BY
            COALESCE(t1."FISCAL_YEAR",t2."FISCAL_YEAR") 

现在为了让查询更容易理解,我这样做了

SELECT
    FISCAL_YEAR "FISCAL_YEAR" ,
    (sum("EXPENCE"."TXN_AMT" )) "exp",
    (sum("INCOME"."TXN_AMT" )) "rev" 
FROM
    Calander ,
    EXPENCE FULL OUTER JOIN INCOME ON
    "EXPENCE"."TXN_DATE" = "INCOME"."TXN_DATE"
WHERE
    "EXPENCE"."TXN_DATE"="Calander"."DAY_DATE" and
    "INCOME"."TXN_DATE"="Calander"."DAY_DATE" 
GROUP BY 
    FISCAL_YEAR
ORDER BY
    FISCAL_YEAR

我在两个查询中得到相同的结果。无论如何结果会有所不同(Ist查询结果是正确的结果)吗? 会对性能产生什么影响?

【问题讨论】:

Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已随 ANSI-92 SQL 标准(超过 20 年前) @marc_s 知道为什么人们今天仍然在使用这种风格,尽管到处都不鼓励它?老实说,我对此很好奇。 @usr: 恐怕很多教练都不是真正的最新的,而是教“旧”的风格——或者只是纯粹的懒惰“已经这样做了 20 年...... ...” 【参考方案1】:

第二个应该更有效,但要验证它,请检查实际的执行计划。同时设置

SET STATISTICS IO ON

在会话上检查两个查询对您的真实数据的逻辑读取。

另一个习惯 - 停止在标识符周围使用双引号,或者准备在某个时候被 QUOTED_IDENTIFIER 设置击中 :)

【讨论】:

小数据集第二个统计明智的效率更高。但是你能解释一下原因吗?在任何情况下,结果都会一样吗? 我相信第一个中的子查询作为单独的分支执行,因此对日历表进行两次扫描和两次聚合。在大多数情况下,第二个可能会得到更好的优化。但是,与往常一样,这取决于数据分布和基数,以及现有索引。 EXPENCE 和 INCOME 表在生产系统中可能包含这么多行,如果我选择第二个查询,是否会导致这两个表之间的笛卡尔连接?【参考方案2】:

第二个查询在性能方面会更好。 在您的第一个查询中,您在两个子查询中使用连接来过滤数据,然后再次连接它们,而您的第二个查询更加优化,因为您通过连接所有三个表来过滤数据。还有一个建议,避免使用旧式连接使您的查询更易读且更好。

【讨论】:

以上是关于这两个查询的性能比较的主要内容,如果未能解决你的问题,请参考以下文章

MySQL查询和静态缓存的性能比较

计算sql查询的性能

查询性能优化

mongodb更新比较频繁,性能下降的厉害怎么办

比较日期查询的性能

多连接和多子查询的性能比较