<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVA & XML & JAVASCRIPT & AJAX & CSS

    Web 2.0 技術(shù)儲備............

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      77 隨筆 :: 17 文章 :: 116 評論 :: 0 Trackbacks
    通過內(nèi)部的計數(shù)器得知:訪問次數(shù)是1071(其中有好多是自己點(diǎn)的:)),人數(shù)不是太理想,本來是想看看上萬人同時訪問的情況:)

    系統(tǒng)資源的占用情況

    內(nèi)存 —— 很理想。SQL占用的內(nèi)存最大也沒有超過65M,一般是在35M左右;asp.net占用的內(nèi)存最大也沒有超過40M,一般是在25M左右。

    CPU:8%左右,由于訪問次數(shù)不多,也不夠集中,所以這個數(shù)值也說明不了什么。自己連續(xù)點(diǎn)了n次下一頁,發(fā)現(xiàn)CPU的使用率飄高,達(dá)到了50%左右。
    但是對于100萬的記錄,AMD XP2000+ 的CPU 幾十毫秒的放映速度,因該是可以接受的,甚至是很理想的吧。
    畢竟服務(wù)器的CPU要比我的快很多吧,而且記錄也很難達(dá)到100萬吧。

    結(jié)果還是很滿意的,但是美中不足的是,我想看一下海量訪問的情況下的效果,
    希望大家再支持一下,多點(diǎn)幾下,謝謝了。呵呵

    另外說明一下:前n頁可以在60毫秒內(nèi)完成,n應(yīng)該是大于500的,小于多少嘛還沒有測試。后n頁就比較慢了,需要500毫秒左右。

    下面討論一下翻頁的技巧吧。
    我沒有用游標(biāo)、臨時表、not in、in 這些方法,并不是說他們的效率不高,而是我還沒有測試過。我只用了 top ,查了兩次表。
    大家也可提供一些其他的方法,我來測試一下,看看在100萬條的情況下的效果。(請不要給在存儲過程里面組串的,看著實(shí)在是太費(fèi)勁了)

     

     討論的前提是在海量數(shù)據(jù)的情況下,至少是在10萬以上的。如果是很少的數(shù)據(jù)呢,那怎么翻都可以了。也差不了多少。

    1.設(shè)置合理的索引
    首先要做的是設(shè)置合理的索引,這個好像經(jīng)常被忽略,至少很少被談起。

    注意:主鍵是索引的一種,而且是最快的一種。如果你都是把主鍵當(dāng)作排序字段的話,那么你已經(jīng)利用了索引。

    不設(shè)置合理的索引的話,會導(dǎo)致查詢速度非常的慢,甚至?xí)斐沙瑫r。

    這方面你可以做一個實(shí)驗(yàn):找一個表,填進(jìn)去10萬條記錄,假設(shè)有ID 、addedDate等字段,在查詢分析器里面執(zhí)行一下

    select top 10 * from table
    應(yīng)該立刻就能出現(xiàn)結(jié)果。

    然后再執(zhí)行 select top 10 * from table order by ID(這時ID字段是主鍵)
    也是立刻就出現(xiàn)了結(jié)果。

    然后再執(zhí)行 select top 10 * from table order by addedDate (這時addedDate字段沒有索引)
    你會發(fā)現(xiàn)速度很慢。

    現(xiàn)在給addedDate 加一個非聚集索引,然后在執(zhí)行上面的查詢語句,速度也變得很快了。

    可見索引神奇的效果!

    這是翻動百萬級記錄最基本的設(shè)置,具體到我的那個論壇的翻頁,我是設(shè)置了BoardID、 replyDate兩個字段作為聯(lián)合索引的。
    因?yàn)槭且谕粋€討論組李翻頁,而且是按replyDate排序的。


    2.只返回需要的記錄
    對于海量數(shù)據(jù),都讀出來做緩存,那是不可想象的(記錄少的話,也要看利用率,一般都是很浪費(fèi)的)。
    所以呢如果一頁顯示20條的話名那就只都讀出來20條,這樣就很省內(nèi)存和時間。

    注意:雖然ADO.NET里面有這個方法
    SqlDataAdapter.Fill(DataSet1,startRecord,maxRecords,srcTable);
    但是他還是要先從SQL里面把查詢語句的查出來的所有記錄都出來,然后在截取指定的記錄數(shù)。這對于SQL來說是一樣的,對于海量數(shù)據(jù)依然會很慢。

    論壇里的首頁用的是select top 20 * from table where boardID = 5 order by replyDate desc
    這樣呢就只返回了20條記錄,再加上索引的功勞,速度是非常快的。

     

     3.盡量減少字段的長度
    一個表可以建很多的字段,但是字段的總長度不能超過8060B,也就是說如果你建了一個char(8060)的字段,就不能在建其他的字段了。

    我在第一次的測試中(星期天的),把主題的所有信息都放在了一個表里面,包括了一個nvarchar(3600)的主題內(nèi)容的字段,復(fù)制記錄的時候發(fā)現(xiàn)非常的慢,
    當(dāng)達(dá)到9萬的時候,就已經(jīng)很慢的,勉強(qiáng)把記錄數(shù)拷貝到了35萬,加了索引,測試了一下,翻頁速度還是可以的,前n也都是很快的,后n頁就很慢了,
    如果再加上查詢那就非常之慢了。

    查看了一下數(shù)據(jù)文件嚇了一跳 —— 他居然占用了1.4G的硬盤空間,怪不得拷貝和查詢都慢的要死呢。

    于是修改了一下表結(jié)構(gòu),把那個nvarchar(3600)的主題內(nèi)容的字段踢了出去,放在一個單獨(dú)的表里面。
    再重新拷貝記錄就非常的快了,很快就把記錄數(shù)從16表成了1048577。昨天的測試就是在這個條件下進(jìn)行的。

    4.技巧
    終于到了翻頁算法的地方了,呵呵沒有等急吧。
    思路呢就是先找到一個標(biāo)志,然后呢把大于(或小于)這個標(biāo)志的前n條記錄取出來。
    什么?沒看懂。沒關(guān)系,我舉個例子吧。

    假設(shè)是按ID倒序的,每一頁顯示10條記錄,有100條記錄,記錄號正好是1到100(怎么這么巧??為了說明方便嘛)

    那么第一頁的記錄就是100到91、第二頁的記錄就是90到81、第三頁的記錄就是80到71......

    我現(xiàn)在要翻到第三頁,那么要找到第21行的記錄的ID的值(也就是80),然后把小于等于80的記錄用top 10 取出來就行了。

    查詢語句

    declare @pageSize int --返回一頁的記錄數(shù)
    declare @CurPage int --頁號(第幾頁)1:第一頁;2:第二頁;......;-1最后一頁。

    declare @Count int
    declare @id int

    set @pageSize=10
    set @CurPage =1

    if @CurPage = -1
    begin
    --最后一頁
    set rowcount @pageSize
    select @id=ID from table order by ID
    end

    --定位
    if @CurPage > 0
    begin
    set @Count = @pageSize * (@CurPage -1) + 1
    set rowcount @Count
    select @id=ID from table order by ID desc
    end

    --返回記錄
    set rowcount @pageSize
    select * from table where ID <=@id order by ID desc

    set rowcount 0


    其中“定位”用了 select @id=ID from table order by ID desc
    這種方法,感覺上是很省內(nèi)存的,因?yàn)橹挥涗浟艘粋€ID,

    然后用 select * from table where ID <=@id order by ID desc
    取得最終需要的記錄

    set rowcount @pageSize 相當(dāng)于 top @pageSize 。


    優(yōu)點(diǎn):無論翻到哪一頁,內(nèi)存的占用情況都不變,多人訪問內(nèi)存也不會不變,很多人呢,還沒有測試出來:)
    缺點(diǎn):單表、單排序字段。

     

     

     http://community.csdn.net/Expert/TopicView3.asp?id=4182510

    發(fā)了這個帖子,回復(fù)的人很多,感謝大家的支持。這里有個誤會我不得不說明一下,免的誤人子弟。

    在帖子里我并不是寫了個算法就完事了,而是說了很多翻動海量數(shù)據(jù)要注意的地方,

    比如建立合理的索引,只返回需要的記錄 ,盡量減少字段的長度 等注意到或沒有注意到的地方。

    最后說的才是算法,可能是我的表達(dá)能力太差了吧,舉的例子給大家?guī)砹苏`會。

    翻頁的語句 ( @pageSize * (@CurPage -1) + 1 )

    --定位
    declare @id int
    select top 41 @id=ID from table order by ID desc

    --顯示數(shù)據(jù)
    select top 20 * from table where ID <=@id order by ID desc

    按照ID倒序排列(也就是按照int類型的字段排序)
    一頁顯示20條記錄,這是顯示第三頁的語句
    @pageSize * (@CurPage -1) + 1 = 20*(3-1) + 1 = 41
    正是因?yàn)镮D是不連續(xù)的所以才需要用第一個語句來定位,如果是連續(xù)的那還用第一條語句做什么呢?

    舉各少量數(shù)據(jù)的例子:
    假設(shè)有10條記錄,ID是:1000,500,320,205,115,110,95,68,4,1。這回不寫連續(xù)的了免的誤會
    一頁顯示兩條記錄,現(xiàn)在要顯示第三頁,那么第三頁的id就是 115,110

    先看第一條語句
    select top 5 @id=ID from table order by ID desc
    不知道大家有沒有看懂這句,這時print @id 得到的結(jié)果是 115。

    再看第二條語句
    select top 2 * from table where ID <=115 order by ID desc
    這時的記錄集就是 115,110,也就是我們所需要的記錄了。


    注意:不需要連續(xù)的ID,也不局限只能按ID排序,你可以換成ReplyDate(最后回復(fù)時間)字段,
    當(dāng)然了declare @id int 要改成 declare @id datetime

    這里的ID 是主鍵,唯一標(biāo)識記錄的字段,它本身就是一種索引,而且是效率最高的索引。

    A.唯一標(biāo)識記錄的字段的值怎么能隨意改動呢,那不亂套了嗎?

    B.主鍵是最快的索引,可能你還沒有意識到(一開始我就不知道,學(xué)了SQL很久以后才知道的),如果你的算法用它作為排序字段,那么速度會很快,會比用其他字段(沒有索引的字段)排序快很多。

    C.用ReplyDate(最后回復(fù)時間)來排序,那么就必須給他建立索引(在海量數(shù)據(jù)的情況下),否則會超時的。


    D.建立索引后,再執(zhí)行添加、修改、刪除會對數(shù)據(jù)庫帶來災(zāi)難性的折磨??
    一開始我也是這么認(rèn)為的,但是為了能夠翻頁,不得不加索引。
    但是接下來的事實(shí)確打消了我的顧慮

    先來看添加。
    100萬條記錄是怎么弄出來的?大家可以看到帖子里有很多標(biāo)題一樣的主題,對了是復(fù)制出來的。
    我先加了16條記錄,然后加上了索引。注意在insert into 之前就已經(jīng)建立好了索引!

    接下來就是insert into table (...) select ... from table 影響的行數(shù):
    16、32、64、128、256、512、1024、2048、4096、8192、16384、32768、65536、
    131072、262144、524288 很快記錄就達(dá)到了100完了。
    最后一次也只不過一兩分鐘(具體的時間忘記了,反正是很快了)。
    同時,論壇也提供了發(fā)貼的功能,只是在批量添加記錄的時候,把一些記錄的最后回復(fù)時間弄成了2006年,
    所以,你發(fā)的帖子不會顯示在第一頁。但是你可以看到,執(zhí)行時間是很快的。

    可見添加的時候是不成問題的,索引是倒序排列的,所以影響的行數(shù)絕對沒有你想象的那么多。

    再來看修改
    看了sp1234的回復(fù),加了修改的功能,只是為了測試,所以呢可以修改標(biāo)題、最后發(fā)表時間、分組ID。
    為什么可以修改這幾個字段呢?標(biāo)題是普通字段,最后發(fā)表時間和分組ID是索引字段。
    修改這幾個字段需要的時間都是很快的,在最后回復(fù)時間的右面有 [改] [刪] 字樣,大家可以試一試。
    同樣,修改的時候,影響的行數(shù)也不是很多。

    最后看刪除
    不多說了,論壇提供了這個功能,試一下就知道了。另外,刪除的時候,不用重新建立一遍索引吧?


    在來說一下使用范圍吧。
    首先呢這只是一種方法,而不是一個通用的存儲過程,也就是說要根據(jù)情況作適當(dāng)?shù)男薷摹?BR>最佳使用環(huán)境:
    單表,單排序字段,可以利用索引。
    注意事項(xiàng):
    排序字段不必連續(xù),最好使用int、datetime類型的字段,字符串型的字段沒有試過,效果可能會略差。
    表可以沒有主鍵,但是對于海量數(shù)據(jù)的情況下,必須建立合理的索引。

    有一個比較致命的限制,大家好像都沒有發(fā)現(xiàn),那就是排序字段的重復(fù)性,
    最好是沒有重復(fù)的,但不是說絕對不能有重復(fù)的記錄,有不要緊,只要不跨頁就行,跨頁的話就會擠掉若干條記錄,
    用時間字段來排序,發(fā)生重復(fù)的記錄的可能性就很小了。


    擴(kuò)展性
    bingbingcha(不思不歸,不孟不E,原來是頭大灰狼) 的回復(fù)很精彩
    -----------------
    這樣的技巧在SQL區(qū)都討論過了..速度是很快的..但是滿足不了需求的..實(shí)用性太差了..現(xiàn)在的企業(yè)需要用到分頁的大部分都是多表查詢..單表分頁滿足不了需求的..

    這個存儲過程可以擴(kuò)展..用臨時表+樓主的方法..是個不錯的選擇..
    -----------------

    對于多表關(guān)聯(lián)查詢,有兩種方法,第一種就是bingbingcha說的 —— “用臨時表+樓主的方法”,這是在海量數(shù)據(jù)的時候唯一可行的方法。
    但是在小數(shù)據(jù)量的時候,這么些就有一點(diǎn)繁瑣,而且不容易歸納到通用的寫法里。

    先來看一下查詢語句據(jù)的寫法:
    聯(lián)合的
    SELECT a.ReplyID, a.TopicID
    FROM dbo.BBS_Reply a INNER JOIN
    dbo.BBS_body b ON a.BodyID = b.bodyID
    where a.ReplyID >10

    單表的

    SELECT ReplyID, TopicID
    FROM dbo.BBS_Reply
    where ReplyID >10

    有沒有看到相同的地方:
    select 顯示的字段
    from 表
    where 條件

    那么單表查詢和多表查詢有什么區(qū)別呢?
    至少有很多的多表(單字段排序)查詢都是可用這種方式的。
    注意:我并沒有說所有的多表(單字段排序)查詢都可以用,看具體情況了。



    這是一個效率最高(需要合理的索引的幫忙),比較通用的翻頁方法。不知道這次我有沒有講明白。

    posted on 2006-03-16 23:14 Web 2.0 技術(shù)資源 閱讀(2311) 評論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲依依成人精品| 亚洲国色天香视频| 日韩在线一区二区三区免费视频 | 在线观看片免费人成视频无码| 免费一级特黄特色大片在线| 偷自拍亚洲视频在线观看99| 亚洲人成网站在线观看青青| 免费人成大片在线观看播放电影| 又黄又大又爽免费视频| 一级毛片免费毛片毛片| 久久久久亚洲AV成人网人人网站| a高清免费毛片久久| 不卡一卡二卡三亚洲| 亚洲阿v天堂在线2017免费| 亚洲国产AV无码专区亚洲AV| 久久久久国产精品免费免费不卡| 亚洲国产精品成人综合色在线婷婷| 亚洲一区免费在线观看| 亚洲一区二区三区成人网站 | 亚洲综合无码AV一区二区| 中国在线观看免费的www| 国产亚洲真人做受在线观看| 99视频在线免费看| ww亚洲ww在线观看国产| 亚洲av高清在线观看一区二区 | 国产成人免费在线| 亚洲码欧美码一区二区三区| 亚洲午夜日韩高清一区| 69视频在线观看免费| 自拍偷区亚洲国内自拍| MM131亚洲国产美女久久| 97在线视频免费播放| 亚洲精华国产精华精华液好用| 最新精品亚洲成a人在线观看| 一级毛片免费视频| 亚洲精品久久无码| 国产V亚洲V天堂无码久久久| 成年女人18级毛片毛片免费 | 三上悠亚电影全集免费| 亚洲成人黄色在线| 国产L精品国产亚洲区久久|