2011-01-26 123 views
0

差异更好的代码开发

select CE1.CLASS_ID, 
     CE1.LOCATION_ID, 
     count(case CE1.FORMAT_ID when 5 then 1 end) as LIVE, 
     count(case CE1.FORMAT_ID when 14 then 1 end) as LB, 
     count(case CE1.FORMAT_ID when 15 then 1 end) as WEB, 
     SUM(DECODE (CE1.ROLE_ID,5,1,0)) FACULTY, 
     SUM(DECODE (CE1.ROLE_ID ,2,1,0)) MODERATOR, 
     SUM(DECODE (CE1.ROLE_ID ,3,1,0)) PANELIST, 
     SUM(DECODE (CE1.ROLE_ID,4,1,0)) PRESENTER, 
     COUNT(CE1.USER_ID) TOT 
    from C_EDUCATION1 CE1 
GROUP BY CE1.LOCATION_ID, CE1.CLASS_ID 

我们正在开发现有系统和我们发现混合使用COUNT和解码。 如果我们理解正确,我们可以转换为以下代码。

select CE1.CLASS_ID, 
     CE1.LOCATION_ID, 
     SUM(DECODE (CE1.FORMAT_ID ,5,1,0)) LIVE, 
     SUM(DECODE (CE1.FORMAT_ID ,14,1,0)) LB, 
     SUM(DECODE (CE1.FORMAT_ID,15,1,0)) WEB, 
     SUM(DECODE (CE1.ROLE_ID,5,1,0)) FACULTY, 
     SUM(DECODE (CE1.ROLE_ID ,2,1,0)) MODERATOR, 
     SUM(DECODE (CE1.ROLE_ID ,3,1,0)) PANELIST, 
     SUM(DECODE (CE1.ROLE_ID,4,1,0)) PRESENTER, 
     COUNT(CE1.USER_ID) TOT 
    from C_EDUCATION1 CE1 
GROUP BY CE1.LOCATION_ID, CE1.CLASS_ID 

OR 所有COUNT

我们想知道在其他性能问题上的分歧,或。 更好的方式存在吗?

+5

我不知道使用CASE与DECODE之间的性能差异,但CASE是ANSI,因此如果DECODE被换出为CASE,查询将更具可移植性。我会考虑将DECODE弃用,但为了向后兼容,它永远不会消失。 – 2011-01-26 17:21:40

回答

4

两者之间没有性能差异。

就个人而言,我倾向于选择基于CASE的解决方案。 CASE是ANSI标准,而不是Oracle特定的功能。来自其他数据库平台的开发人员可能不得不查找DECODE语句的语义。 CASE对于开发者来说也是相当明显的,无论他们熟悉哪种语言。实际上每种语言都有CASE语句,因此任何开发人员都应该能够快速了解​​您正在做什么。

话虽这么说,我会倾向于主张像

SELECT ce1.class_id, 
     ce1.location_id, 
     SUM(CASE WHEN format_pkg.is_live(format_id) = 'Y' THEN 1 ELSE 0 END) live, 
     SUM(CASE WHEN format_pkg.is_lb( format_id) = 'Y' THEN 1 ELSE 0 END) lb, 
     ... 

这使用情况下,从第一个查询中,SUM从第二,并增加了一些功能的调用,以确定哪些类型的格式/角色正在讨论中。这可以防止你必须对整个地方的FORMAT_ID/ROLE_ID值进行硬编码。而使用SUM而不是COUNT会更清楚一些,因为对于开发人员COUNT排除NULL值可能并不明显。