STUDENT(学生信息表) ID NUMBER(8) N 学号
NAME VARCHAR2(10) N 姓名
AGE NUMBER(4) N 年龄
REMARK VARCHAR2(100) Y 备注 -----------------------------------
SELECT *
FROM
(
SELECT RESULT.*, ROWNUM rn
FROM
(
SELECT a.id
|| '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a.REMARK
FROM STUDENT a
ORDER BY a.AGE DESC
) RESULT
)
WHERE rn >= 101 AND rn <= 200
---------------------------------------
以上sql是查询出年龄是第101名到第200名之间的100名学生(假定年龄不重复)的信息并将信息进行字符串连接(用“|”隔开) ?优化上面那条sql语句,尽可能的提高查询效率
可以不基于以上sql语句,只要返回结果集相同,用其他思路实现效率的提高亦可*************************************************************************************
以下我的方法是不是最优的? 请教有没有最优的方法.
select * from (select a.id || '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a.REMARK,row_number ()over(ORDER BY a.AGE DESC) aaa
from r_student a) b
where b.aaa between 101 and 200;
NAME VARCHAR2(10) N 姓名
AGE NUMBER(4) N 年龄
REMARK VARCHAR2(100) Y 备注 -----------------------------------
SELECT *
FROM
(
SELECT RESULT.*, ROWNUM rn
FROM
(
SELECT a.id
|| '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a.REMARK
FROM STUDENT a
ORDER BY a.AGE DESC
) RESULT
)
WHERE rn >= 101 AND rn <= 200
---------------------------------------
以上sql是查询出年龄是第101名到第200名之间的100名学生(假定年龄不重复)的信息并将信息进行字符串连接(用“|”隔开) ?优化上面那条sql语句,尽可能的提高查询效率
可以不基于以上sql语句,只要返回结果集相同,用其他思路实现效率的提高亦可*************************************************************************************
以下我的方法是不是最优的? 请教有没有最优的方法.
select * from (select a.id || '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a.REMARK,row_number ()over(ORDER BY a.AGE DESC) aaa
from r_student a) b
where b.aaa between 101 and 200;
FROM (SELECT ROWNUM AS C1, a.id || '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a.REMARK as TT
FROM TABLE WHERE ROWNUM < 200 order by AGE) A
WHERE A.C1>101
SELECT ROWNUM AS C1, a.id || '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a.REMARK as TT
FROM TABLE WHERE ROWNUM < 200 order by AGE
应该是先取了ROWNUM < 200的记录后再按AGE排序的,我做的测试是这样的。楼主的sql执行时间是多少?原来的执行时间又是多少?此问题继续关注中......
select * from (
select rownum as countrownum,tt from(select a.id || '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a."REMARK" as tt
from student a
order by age desc ) t1
where rownum < 6 )
where (countrownum >= 4 )
select a.id || '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a.REMARK
from r_student a where (select count(*) from r_student where AGE>a.AGE) between 100 and 199
select a.id || '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a.REMARK from r_student t where rowid in
(
SELECT rid FROM
(
SELECT T1.rowid rid, rownum as linenum FROM
(
SELECT a.rowid FROM r_student a order by age desc ) T1
WHERE rownum < Overnumber
) WHERE linenum >= Startnumber
) order by age desc;
注意ORDER的时候尽量要对一个重复的相对来说少一些的字段进行排序.要不......会粉慢的先取所有的ROWID和索引字段再对相应的数据进行排序这样会快一些至少对于我的数据.可能楼主的数据中这一字段重复的会高一些...这个一方法是速度最稳定的.至少是我试过的许多种方法中..你可以测试一下我测试在我的表中一个八十万的表中..库分的高速缓存是24M进行的查询的时候是0.5S左右最高没有超过0.6S.不论是第几页...楼主的方法感觉对后面几页的速度不利
效率显然异见..对于这里我想讲的就是多对ROWID和索引结合进行查询永远是最快的.当然我懂的也只是一个皮毛希望有高手出来可以指正.
smallflaybird(bird鸟) 介绍的方法在我的系统上试了一下,大概只要0.234秒,挺快的.
顺便说一下我的系统,我用的是PL/SQL Developer ,测试的数据库表中有196608条记录,
其中 ID 是顺序排列的,
NAME 是同一个名,
AGE 是随机产生的 10-90之间的值,重复的应该很多,
REMARK 是备注,都是一样的值,
其中 ID是主键,没有建索引,
呵呵,继续深入研究中.....
------
是这样啊,那我的肯定不行,至少数量上就不对了原来那么慢啊,我这只有几条数据所以看不出来。
smallflaybird(bird鸟) 的方法,用时0.109秒
waterfirer(水清) 的方法还是很慢,
用我的方法速度有点减慢,大约0.265秒,
sasacat(傻傻猫) 第二次提供的方法,也很快,用时大约为0.109秒看来,我的方法还是不行,用索引还是有一定用处的.
而且我看了一下你们都是先对所有的数据进行了拼接之后再进行排序取相应的数据段的这样的话如果服务器内存并不高或者是并发量比较高的情况下速度一定会急剧下降的.特别是有热区的时候...这种情况会死人的
刚刚起床在吃饭有兴趣继续讨论
至于
sasacat(傻傻猫) 第二次提供的方法,也很快,用时大约为0.109秒
关于他的速度我想不通为什么这么快..莫非是你的服务器高速缓存非常的大?...研究ING..
smallflaybird(bird鸟) 的方法,用时0.109秒到0.125秒之间,
我的方法0.375秒,哈
waterfirer(水清) 的方法还是很慢,我有些不明白的地方想问smallflaybird(bird鸟) ,为什么建索引不能在重复太多的字段的建?
还有你提供的方法,最内层是将AGE字段排序,那样会不会很慢啊?建了索引之后会加快速度吗?
实在不明白,请大侠指教! 谢谢了
smallflaybird(bird鸟) 的方法,用时0.109秒到0.125秒之间,
我的方法比较慢了,最快的要0.813秒,哈看来我的方法不行了,数据越多越慢啊,sasacat(傻傻猫) 第二次提供的方法应该改一下,改成这样就好了
感觉上和smallflaybird(bird鸟)的方法差不多,只是少一个ORDER BYselect rownum countrownum,b.*
from
(
select * from
(
select rownum as countrownum,tt
from(
select a.id || '|'
|| a.name
|| '|'
|| a.AGE
|| '|'
|| a."REMARK" as tt
from r_student a
order by age desc
) t1
where rownum <= 200
)
where (countrownum >= 101 )
) b
smallflaybird(bird鸟) 的方法,用时0.141-0.172秒之间,
我的方法....天啊,8.14秒,哈的确如楼上所说 取哪一段的数据的速度都平稳的...sasacat(傻傻猫) 的方法快应该快在: 第二层rownum <= 200 只取了200条记录参与以后的查询,所以快,取其他位置的段落就不行了.
我的方法就是取到10000~10100 取到相应的ROWID再到相应的ROWID地址去读出数据拼起来这个速度和原理上完全是两码事情
刚才本来想发的.但是CSDN的三条原则我又是一个想到哪就说哪人..同时我自己也粉忙公司一堆的事情..
最后问一个弱智问题,ROWID是物理的地址吗,会不会随着ORDER BY 排序而变化?