问题:一个表student中有班级classid,学号id,成绩grade 写个sql 查找比该班平均成绩高的学生的班级classid,学号id,成绩grade
方法1:题目带的sql
select a.classid,a.id,a.grade
from student a
where a.grade > (select avg(grade) from student where classid = a.classid);
方法2:_________________________(要求写的sql)select s.id,s.classid,s.grade from student s,(select avg(grade),classid from student group by classid) d
where s.classid = d.classid and s.grade > d.avg(grade);
写完之后,要说明哪种方法效率高。
我就知道写SQL,我想知道上面两种方法哪种效率高点?为什么?
方法1:题目带的sql
select a.classid,a.id,a.grade
from student a
where a.grade > (select avg(grade) from student where classid = a.classid);
方法2:_________________________(要求写的sql)select s.id,s.classid,s.grade from student s,(select avg(grade),classid from student group by classid) d
where s.classid = d.classid and s.grade > d.avg(grade);
写完之后,要说明哪种方法效率高。
我就知道写SQL,我想知道上面两种方法哪种效率高点?为什么?
解决方案 »
- Variant conversion error for variable :V4c错误求解。
- oraclexe安装完成后可以使用http://管理,请问怎么在web里面导入数据库呢?
- 行转列,大家帮帮忙。
- 关于用绿色软件PL/SQL 访问远程服务器的oracle数据库的问题
- 数据库TURNING的,老难题,高手请进
- 安装Oracle失败!
- 一个函数输出多个值,急啊!
- 如何判断pl/sql中读取的文件不为空?
- 无意中发现我也有了“星”,高兴之余不忘大家对我的关照,所以特来散分。。
- linux下安装oracle11gR2,到86%卡主了
- 请问有关raid的问题在哪个论坛?
- 怎样删除WindowsODBC中Oracle的数据访问驱动程序
不过最好还是看执行计划
(select avg(grade) from student where classid = a.classid)
第二种中的子查询
select avg(grade),classid from student group by classid
因为这个对比
s.grade > d.avg(grade);
要被调用count(*)次!
已用时间: 00: 00: 00.00
SQL> create table student as
2 select mod(level - 1,10) + 1 classid, level id, trunc(dbms_random.value* 100) grade from dual
3 connect by level <1000000;表已创建。已用时间: 00: 00: 16.51
SQL> exec dbms_stats.gather_table_stats('TEST','STUDENT');PL/SQL 过程已成功完成。已用时间: 00: 00: 01.42
SQL> select a.classid,a.id,a.grade
2 from student a
3 where a.grade > (select avg(grade) from student where classid = a.classid);已选择499582行。已用时间: 00: 00: 09.78执行计划
----------------------------------------------------------
Plan hash value: 1393824611--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49950 | 1756K| 1234 (20)| 00:00:15 |
|* 1 | HASH JOIN | | 49950 | 1756K| 1234 (20)| 00:00:15 |
| 2 | VIEW | VW_SQ_1 | 10 | 260 | 686 (28)| 00:00:09 |
| 3 | HASH GROUP BY | | 10 | 60 | 686 (28)| 00:00:09 |
| 4 | TABLE ACCESS FULL| STUDENT | 998K| 5853K| 530 (7)| 00:00:07 |
| 5 | TABLE ACCESS FULL | STUDENT | 998K| 9755K| 530 (7)| 00:00:07 |
--------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------- 1 - access("CLASSID"="A"."CLASSID")
filter("A"."GRADE">"VW_COL_1")
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
37655 consistent gets
0 physical reads
0 redo size
10315229 bytes sent via SQL*Net to client
366740 bytes received via SQL*Net from client
33307 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
499582 rows processedSQL> Select s.Id, s.Classid, s.Grade
2 From Student s,
3 (Select Avg(Grade) Avg_Grade, Classid From Student Group By Classid) d
4 Where s.Classid = d.Classid
5 And s.Grade > d.Avg_Grade;已选择499582行。已用时间: 00: 00: 09.70执行计划
----------------------------------------------------------
Plan hash value: 2637888210--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49950 | 1756K| 1234 (20)| 00:00:15 |
|* 1 | HASH JOIN | | 49950 | 1756K| 1234 (20)| 00:00:15 |
| 2 | VIEW | | 10 | 260 | 686 (28)| 00:00:09 |
| 3 | HASH GROUP BY | | 10 | 60 | 686 (28)| 00:00:09 |
| 4 | TABLE ACCESS FULL| STUDENT | 998K| 5853K| 530 (7)| 00:00:07 |
| 5 | TABLE ACCESS FULL | STUDENT | 998K| 9755K| 530 (7)| 00:00:07 |
--------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------- 1 - access("S"."CLASSID"="D"."CLASSID")
filter("S"."GRADE">"D"."AVG_GRADE")
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
37655 consistent gets
0 physical reads
0 redo size
10315229 bytes sent via SQL*Net to client
366740 bytes received via SQL*Net from client
33307 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
499582 rows processedSQL> spool off
我的测试结果,好像2比1还要快点。
具体说是不是会更好,还取决于运行SQL当时的资源状况,比如说内存,后者的瞬态内存消耗显然会要高于前者.如果没有足够的资源支持,原本可以高效运行的SQL也会变成低效率的。
用这个分析函数,是不是能更快点?
SELECT *
FROM (SELECT A.CLASSID, A.ID, A.GRADE,
AVG (GRADE) OVER (PARTITION BY CLASSID) AVGGRADE
FROM STUDENT A)
WHERE GRADE > AVGGRADE