实现员工职位统计查询的两种方法,哪种执行效率更高?
关于两种SQL查询方法的效率对比分析
嘿,这个问题问到点子上了——SQL查询的效率优化确实是日常开发里经常要琢磨的事儿!先帮你理清楚两种常见的实现方式,再对比它们的效率差异:
第一种方法:单表扫描+条件聚合(你给出的DECODE写法)
这是最直接的实现方式,通过DECODE(Oracle专属)或者标准SQL的CASE WHEN,在一次表扫描中完成所有统计计算:
-- 修正了你原SQL里的别名错误(第三个列别名应该是NumOfVP而非NumOfPres) SELECT COUNT(DECODE(job_id, 'AD_PRES', 1, 0)) AS NumOfPres, SUM(DECODE(job_id, 'AD_PRES', salary, 0)) AS SumSalaryP, COUNT(DECODE(job_id, 'AD_VP', 1, 0)) AS NumOfVP, SUM(DECODE(job_id, 'AD_VP', salary, 0)) AS SumSalaryVP FROM EMPLOYEES;
如果用标准SQL兼容的CASE WHEN写法(更通用,适合MySQL、PostgreSQL等其他数据库):
SELECT COUNT(CASE WHEN job_id = 'AD_PRES' THEN 1 END) AS NumOfPres, SUM(CASE WHEN job_id = 'AD_PRES' THEN salary END) AS SumSalaryP, COUNT(CASE WHEN job_id = 'AD_VP' THEN 1 END) AS NumOfVP, SUM(CASE WHEN job_id = 'AD_VP' THEN salary END) AS SumSalaryVP FROM EMPLOYEES;
第二种方法:多表扫描/拆分查询(常见的UNION ALL写法)
另一种常见实现是拆分两次查询,用UNION ALL合并结果(如果需要转置成一行可以再做聚合,先看基础写法):
SELECT 'AD_PRES' AS job_type, COUNT(*) AS NumOfJob, SUM(salary) AS SumSalary FROM EMPLOYEES WHERE job_id = 'AD_PRES' UNION ALL SELECT 'AD_VP' AS job_type, COUNT(*) AS NumOfJob, SUM(salary) AS SumSalary FROM EMPLOYEES WHERE job_id = 'AD_VP';
效率对比结论:第一种方法(单表扫描)效率更高
原因很直观:
- 第一种方法只需要对
EMPLOYEES表进行一次扫描(不管是全表扫还是走job_id索引),所有统计计算都在这一次扫描中完成,IO开销最小。 - 第二种拆分查询的方式,会对表进行两次独立扫描,IO量直接翻倍。当表数据量很大时,这种差异会非常明显——哪怕
job_id上有索引,两次索引扫描的开销也比一次大。
额外提个小优化:如果你的EMPLOYEES表中大部分数据都不是AD_PRES或AD_VP,可以给第一种方法加上WHERE job_id IN ('AD_PRES', 'AD_VP'),这样能进一步减少扫描的数据量,效率会更高:
SELECT COUNT(CASE WHEN job_id = 'AD_PRES' THEN 1 END) AS NumOfPres, SUM(CASE WHEN job_id = 'AD_PRES' THEN salary END) AS SumSalaryP, COUNT(CASE WHEN job_id = 'AD_VP' THEN 1 END) AS NumOfVP, SUM(CASE WHEN job_id = 'AD_VP' THEN salary END) AS SumSalaryVP FROM EMPLOYEES WHERE job_id IN ('AD_PRES', 'AD_VP');
内容的提问来源于stack exchange,提问作者Ангел Хаджиев
相关产品推荐
相关产品推荐

