作者:戰鬥民族就是幹
轉載請註明地址:http://www.cnblogs.com/prayers/p/8986498.html
普通分頁
當需要深度分頁的時候,比如查詢第10000頁資料,每頁顯示10條,意味著需要提取前10000 x 10 頁的資料,並將這100000條資料快取在記憶體中,然後在記憶體中進行排序。最後返回最後10條即使用者想要的第100000頁資料。
缺點:
1、首先需要在記憶體快取100000條資料需要佔用大量的記憶體
2、並且在記憶體中對100000條資料進行排序也非常消耗CPU
因此普通分頁方式比較適合返回TOPN條資料,翻頁越翻到後面,分頁查詢效能越差,即使你開啟了resultQueryCache
Cursor分頁
Solr中的遊標是一個邏輯概念,它不會在伺服器上儲存任何資訊,而是返回一個下一頁資料起始位置”Mark”標記值給使用者,該標記表示著當前分頁起始位置在查詢匹配的整個索引結果集中的絕對索引位置。
想要在Solr中使用遊標,你需要指定一個cursorMark引數比如:cursorMark=*,你可以理解為它跟start=0類似。 然後此時Solr除了會返回一個TopN的結果集,同時還附帶返回一個nextCursorMark值, nextCursorMark表示遊標下一次遍歷的起始位置即下一次分頁從nextCursorMark位置開始返回。 nextCursorMark值是查詢匹配結果集中的資料索引位置的編碼值,每一次分頁查詢都需要帶上cursorMark引數即cursorMark=nextCursorMark值(第一頁除外),你可以重複這個過程,直到Solr返回的nextCursorMark=cursorMark, 那麼就表明此時已經沒有下一頁了
注意:
1、cursorMark和start引數是互斥的,你不能同時指定這兩個引數,或者也可以同時指定這兩個引數,但是此時start引數必須等於零
2、sort語句必須包含唯一主鍵域,如果id是你的主鍵域,那麼sort引數可以像這樣設定: sort=idasc,name asc。 但是你不能設定sort=name desc
因為遊標標記是根據結果集中每個索引文件的排序值進行計算出來的,這意味著如果兩個文件的排序值相同,那麼它們生成的遊標值也是相同的,這個就是要求sort語句必須包含主鍵的原因
使用用例如下:第一次分頁必須使用cursorMark=*
http://localhost:8080/solr/b2b/select?q=cmmdtyName:手機&sort=id asc&fl=id,cmmdtyCode&wt=json&indent=true&cursorMark=*&rows=1
返回結果集如下:
{ responseHeader: { status: 0, QTime: 2 }, response: { numFound: 484, start: 0, docs: [ { id: "P2_000000010207451749_0070173948", cmmdtyCode: "000000010207451749" } ] }, nextCursorMark: "AoE/AVAyXzAwMDAwMDAxMDIwNzQ1MTc0OV8wMDcwMTczOTQ4" }
查詢下一頁的用例:
http://localhost:8080/solr/b2b/select?q=cmmdtyName:手機&sort=id asc&fl=id,cmmdtyCode&wt=json&indent=true&cursorMark=AoE/AVAyXzAwMDAwMDAxMDIwNzQ1MTc0OV8wMDcwMTczOTQ4&rows=1
這裡的cursorMark引數值, 它需要與上一次分頁查詢結果集裡返回的nextCursorMark屬性值保持一致,直到返回的nextCursorMark等於當前的cursorMark,也就表明分頁到底了
由於每一次請求下一頁都需要上一頁查詢返回的nextCursonMark遊標,所以無法實現指定頁的查詢請求,只能一頁一頁的翻下去,類似於連結串列