Help me!海量数据多表联合查询的问题!!
现有一个文章数据库,要实现查询指定记录数的数据(如select top 200),又要查询与其相关的表,最后实现输出指定记录的功能。(问题有点长,但是描述很详细,希望高手耐心看完并给与解答,谢谢!)
与之相关的数据库结构如下:
作品表:books(bookid<作品ID>,btitle<作品名称>,classid<作品类别ID>,hits<作品点击数>)记录数 万级
分卷表:bookj(jid<分卷ID>,jtitle<分卷名称>,bookid<分卷所属作品ID>) 记录数 十万级
章节表:bookz(zid<章节ID>,ztitle<章节名称>,bookid<章节所属作品ID>,jid<章节所属分卷ID>,updates<本章更新时间>) 记录数 百万级
分类表:class(classid<分类ID>,classname<分类名称>)
(主键、索引都是默认id,递增<如bookid,jid,zid,classid 都是主键和索引?>,其他字段均未做任何索引或优化等)
具体描述:要查询按点击数(hits)降序的前200部作品,并显示
作品名称(btitle),所属分类(classname,class.classid=books.classid),该作品最新章节(ztitle,bookz.bookid=books.bookid,按updates降序),最新章节所属分卷(jtitle,bookj.jid=bookz.jid)
要求输出格式如下(类似):
分类名称 作品名称 分卷名称 章节名称 点击数
TestClass1 TestBook1 Testjuan1 TestChap1 100
TestClass2 TestBook2 Testjuan2 TestChap2 90
TestClass3 TestBook3 <NULL> <NULL> 80
TestClass4 TestBook4 Testjuan3 TestChap3 70
其中Books表里面的内容,对应的Boosj和Bookz里面可能找不到内容(因为该作品还没有章节),但是又要求输出(即使是空值),这样的话,我原先的sql语句(在底下)就不行了(因为过滤了空记录),我不知道left join 或者right join怎么用……
<----
原先用的是,嵌套循环,即,查询作品->查询所属分类->查询最新章节->查询其所属分卷,
用while循环,嵌套查询,输出(我用asp编写的)。
发现当要显示的记录数较大(200)的时候,速度很慢,效率太低(mssql占用cpu近100%,几乎死掉,最后用时近30秒),不得不放弃了。还有,随着要查询的记录增大,耗时几乎平方级增加!
然后改写后,大致如下
select top 200 a.bookid,a.btitle,a.classid,a.hits,b.jtitle,b.jid,c.ztitle,d.classname from books as a join bookj as b on a.bookid=b.bookid join bookz as c on a.bookid=c.bookid join class as d on a.classid=d.classid where zid = (select top 1 zid from bookz as c where c.bookid=a.bookid order by c.updates desc,c.zid desc) and b.jid = c.jid order by a.hits desc
---->
当查询较大记录时(同样200),效率提高很多(用时3-4秒),而且不管要查询的记录数多少,时间都差不多。
已经优化不少了,但是个人觉得远远不够!!(因为结果是秒级,而不是毫秒级的~~)我对sql语句研究不深,以上代码仅仅是经过多番网上搜索相关资料总结得来的,现学现用的,应该存在不少问题或者弯路。我发现没有经过系统的学习,自行泛泛搜索、研究是一件极度不明智的行为。有时候高手的一句有针对性的指点可以事半功 N 倍!!!
还有,因为要做个排行榜,所以不只是按照hits排序,也有其它的如favs(收藏数)排行,只是我没有列举而已。查询后生成Html(总共14个文件,就是14个排行榜),判断后,用For Next循环14次,总耗时 75 秒 左右!!我觉得效率太低了,我知道关键就是那个很长的sql语句select那里很费时(那个For Next具体实现方法不在讨论范围),但是又不知如何优化???
因此,在此恳请高手指点一下,如何设计代码,或者改动数据库,可以符合我的要求,以及效率可以更高一些??用mssql存储过程最好。而且最好能给出asp的调用代码(我用asp写的程序)