这两个查询的性能比较
Posted
技术标签:
【中文标题】这两个查询的性能比较【英文标题】:Performance comparison of these two queries 【发布时间】:2014-04-08 10:10:14 【问题描述】:我正在使用此查询来获取结果,其中Calander
(主键:DAY_DATE
)包含有关时间的所有连续信息(即日期、季度、年份等),EXPENCE
和 INCOME
都有列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】:第二个查询在性能方面会更好。 在您的第一个查询中,您在两个子查询中使用连接来过滤数据,然后再次连接它们,而您的第二个查询更加优化,因为您通过连接所有三个表来过滤数据。还有一个建议,避免使用旧式连接使您的查询更易读且更好。
【讨论】:
以上是关于这两个查询的性能比较的主要内容,如果未能解决你的问题,请参考以下文章