也可不用临时表,而把它做为子查询,这样就能用一个复合SQL语句查询出来,而且性能应该比用临时表更佳。select ...
from (select top 200 ... from ... where ... order by ... desc) as TOP200, ...
where ...
order by ... desc你自己完成它吧。

解决方案 »

  1.   

    To:zhangshenghua(张胜华) 很晚了,明天再测试你的方法,先谢过……睡觉去了^_^
      

  2.   

    你把现存索引都改为降序试试,并把books表的索引的hits改为前导列,其后再排bookid等等
      

  3.   

    To:zhangshenghua(张胜华)
    ====================
    你的思路貌似不错,但是你可以具体一些么?我测试了一早上,都没成功(我很菜,不得不慢慢试 :(  )……
    ====================To:LouisXIV(夜游神) 
    ====================
    你把现存索引都改为降序试试,并把books表的索引的hits改为前导列,其后再排bookid等等
    ====================
    我上面说过了,不只是要得到hits排序(只是举例而已),还有其它诸如favs(收藏数)的排序的……
      

  4.   

    你可真懒啊,接着:select c.classname, t.btitle, j.jtitle, z.ztitle, t.hits
    from (select t.bookid, t.btitle, t.classid, t.hits, max(z.updates) updates
    from (select top 200 bookid, btitle, classid, hits from books) t
    left join bookz z on z.bookid = t.bookid
    group by t.bookid, t.btitle, t.classid, t.hits) t
    left join bookz z on t.bookid = z.bookid and t.updates = z.updates
    left join bookj j on z.bookid = j.bookid and z.jid = j.jid, class c
    where t.classid = c.classid
    order by t.hits desc;
      

  5.   

    实际执行计划:
    1)找到点击频率前200名的书;
    2)查找上述各书的最新修改时间(若无章节则填充NULL),并中转第1步的结果数据;
    3)根据修改时间查找各书最新修改的章节,并组合最终结果数据,最后排序;为提高“根据修改时间查找各书最新修改的章节”的执行效率,请在bookz.updates上添加索引(非聚集、非唯一)。请在这里反馈百万数量级下的执行时间(我估计在1秒内)。
      

  6.   

    SELECT TOP 200 A.bookid, A.btitle, B.jtitle, C.ztitle, A.hits, D.classname, MAX(C.updates) 
          AS UPDATES
    FROM dbo.books A LEFT OUTER JOIN
          dbo.bookj B ON A.bookid = B.bookid LEFT OUTER JOIN
          dbo.bookz C ON A.bookid = C.bookid AND B.jid = C.jid LEFT OUTER JOIN
          dbo.class D ON A.classid = D.classid
    GROUP BY A.hits, A.bookid, A.btitle, B.jtitle, C.ztitle, D.classname
    ORDER BY A.hits DESC, A.bookid DESC
      

  7.   

    如果考虑ZID最大
    SELECT TOP 200 BOOKID, BTITLE, JTITLE, ZTITLE, HITS, CLASSNAME, MAX(ZID) 
          AS ZID
    FROM (SELECT A.BOOKID, A.BTITLE, B.JTITLE, C.ZTITLE, A.HITS, D .CLASSNAME, C.ZID, 
                  MAX(C.UPDATES) AS UPDATES
            FROM DBO.BOOKS A LEFT OUTER JOIN
                  DBO.BOOKJ B ON A.BOOKID = B.BOOKID LEFT OUTER JOIN
                  DBO.BOOKZ C ON (A.BOOKID = C.BOOKID AND B.JID = C.JID) 
                  LEFT OUTER JOIN
                  DBO.CLASS D ON A.CLASSID = D .CLASSID
            GROUP BY A.HITS, A.BOOKID, A.BTITLE, B.JTITLE, C.ZTITLE, D .CLASSNAME, 
                  C.ZID) A
    GROUP BY BOOKID, BTITLE, JTITLE, ZTITLE, HITS, CLASSNAME
    ORDER BY HITS DESC, BOOKID DESC
      

  8.   

    不好意思,我写的排序放错地方了,应该是这样的:select c.classname, t.btitle, j.jtitle, z.ztitle, t.hits
    from (select t.bookid, t.btitle, t.classid, t.hits, max(z.updates) updates
    from (select top 200 bookid, btitle, classid, hits from books order by hits desc) t
    left join bookz z on z.bookid = t.bookid
    group by t.bookid, t.btitle, t.classid, t.hits) t
    left join bookz z on t.bookid = z.bookid and t.updates = z.updates
    left join bookj j on z.bookid = j.bookid and z.jid = j.jid, class c
    where t.classid = c.classid;再补充一点:如果不考虑其它性能(数据更新不频繁,影响貌似较小),最好在books.hits、bookz.updates上都添加索引(聚集、降序、、非唯一),将显著提高本查询的性能。另外,Athoncj(阿龙)给的SQL貌似错误的。
      

  9.   

    To:zhangshenghua(张胜华) 
    ====================
    初步测试了你的方法,发现会有作品重复(所影响的行数为 217 行),可能是因为有章节的updates时间是相同的……
    还有,我今天研究了一天的代码,跟你的比较了一下(一起执行),发觉貌似我的效率更高一些?(20多万章节,占用数据库空间1.7G!总时间2秒<查询分析器右下角得到的,我不知道在哪里看,汗!>)我的:查询1:查询成本(相对于批处理):14.43%
    你的:查询2:查询成本(相对于批处理):85.57%只是在我的代码中,假如最新章节为空(新书,未有任何章节),则该作品不显示(与我想要的结果稍有出入)
      

  10.   

    To:Athoncj(阿龙)
    =====================
    你的方法还未测试,明天再看,很晚了,睡觉先……^_^
      

  11.   

    若更新时间相同,则取zid最大的(经复杂运算后,必须在最后重新排序,因此末尾加了order by子句):select c.classname, t.btitle, j.jtitle, z.ztitle, t.hits
    from (select t.bookid, t.btitle, t.classid, t.hits, max(convert(varchar, z.updates) + z.zid) updates_zid
    from (select top 200 bookid, btitle, classid, hits from books order by hits desc) t
    left join bookz z on z.bookid = t.bookid
    group by t.bookid, t.btitle, t.classid, t.hits) t
    left join bookz z on t.bookid = z.bookid and t.updates_zid = (convert(varchar, z.updates) + z.zid)
    left join bookj j on z.bookid = j.bookid and z.jid = j.jid, class c
    where t.classid = c.classid
    order by t.hits desc;
    我能写出的最快、最简单、最紧凑的,且完全符合要求的代码就是这样,没有优化空间了。
    不要同时两个大规模查询,这样后执行的一定吃亏,因为系统未来得及释放被第一个查询消耗的资源。
    自动计算一个查询的时间消耗(毫秒级):declare @d as datetime;
    declare @c as int;
    select @d = getdate();//执行查询SQL;select @c = datediff(ms, @d, getdate());
    select @c milliseconds;
      

  12.   

    靠,帖子也不来结了?
    帮你解决问题了,完了还要说我的比你的那个还慢,I服了YOU。拉你进黑名单。
      

  13.   

    To:zhangshenghua(张胜华)
    =================================
    靠,帖子也不来结了?
    帮你解决问题了,完了还要说我的比你的那个还慢,I服了YOU。拉你进黑名单。
    =================================
    这话有些严重了
    问题还是没有很好地解决啊你的的确比我的要慢的,我也不知道怎么回事
    没时间仔细测试了,还有别的东西要做
    很感谢你了!!!不知道我有多少分,怎么给:(  我在CSDN没混过多久,大多只是看贴,自己很少发文和回帖的不好意思了随便给你一些分吧
    帖子就先不结了(其实我也不怎么懂得结贴……),看看还有没有人有更好的思路的
    =================
    看了一下,我只有100分:( 给你们70分了,手头留30分以备不时之需 :)
      

  14.   

    1)从SQL语句的执行流程分析,你的不可能更快,尽管你那个忽略了没有章节的书(我的符合要求,没有忽略,这会增加一些开销),因为你是最后才排序取前200的;
    2)查询策略与索引紧密相关,我的查询要求你加两个索引,你加了没有?加与不加差别可大了;
    3)我也不知道怎么给分(从没问过问题,只回答过问题);
      

  15.   

    To:zhangshenghua(张胜华) 
    ==================
    1)从SQL语句的执行流程分析,你的不可能更快,尽管你那个忽略了没有章节的书(我的符合要求,没有忽略,这会增加一些开销),因为你是最后才排序取前200的;
    2)查询策略与索引紧密相关,我的查询要求你加两个索引,你加了没有?加与不加差别可大了;
    3)我也不知道怎么给分(从没问过问题,只回答过问题);
    ==================
    我现在的不是上面我给出的那个了,又经过一些自认为的优化,反正最后查询都会稍快一些的我也不知道哪里的问题索引我应该加了的(就是不知加得对不对:(  )
    感谢你的帮助,现在已经没空在这个问题上面纠缠太久再次感谢!!!
      

  16.   

    把你的“优化”贴出来啊~~~~~~牛皮佬!
    你能写出更快的,我就跟你混了,NND。
      

  17.   

    To:zhangshenghua(张胜华) 
    ====================
    把你的“优化”贴出来啊~~~~~~牛皮佬!
    你能写出更快的,我就跟你混了,NND。
    ====================
    晕了,今天进来转转,竟然发现你又不满了不知我哪里得罪你了,你说话如此“损”……
    这个代码已经没有用了,因为我重新设计了数据库,把最新章节存入books表了,免得每次都查询那个海量表,毕竟增加章节不是特别频繁,一天有个几十上百的就不错了
    至于我以前的思路,我也不知道是什么思路,具体代码也不贴了,免得怡笑大方。
    我也没说你的方法就不好了,其实是我还不是很理解你的思路当时只好按照自己的思路随便写了——(都是菜鸟的理解,你是高手看了一笑而过吧。。)
    我吹牛皮?算了,算我吹牛皮了讨论这个已经没有意义了,麻烦你“大人有大量”,不要再计较了,OK?
    我是菜鸟,希望能跟各位前辈高手多学学========================
    最后告诉大家一声,其实 zhangshenghua(张胜华) 是高手,而且很热心,虽然他对我有意见只要你的脸皮可以像我一样厚,不对某些人的某些话在意,你是可以学到很多的。
      

  18.   

    借口不结帖,在CSDN可能不受欢迎。这是别人说的,我个人不在意(除了最近一个月,我很少在CSDN混,尽管已经注册好几年了)。
      

  19.   

    要分你就拿去吧。
    原以为我是初学者,来CSDN学习的,没想到,很多人眼睛就盯着那些分,那些很虚的东西
    我故意不结帖?我有必要吗?不结帖貌似会被强制结帖并扣什么信誉分的(我刚刚知道)。。虽然我都不在意这些
    算了,自己没技术,怪不得别人
    再次感谢你们这些高手的指点!!