摘要:整個(gè)代碼形似代碼它的原理很簡單,其實(shí)就是利用可以利用的來加速分頁。需要提醒的是,上需要有才有意義,而且它可以有多列采用這種方式的分頁可以避免上述分頁的潛在危險(xiǎn)當(dāng)頁數(shù)達(dá)到一定量之后,分頁速度會嚴(yán)重下降。
凡事做過頁面的,一般對分頁不會陌生,也不會覺得它有多難:就是limit + offset的組合就可以了呀。但是,危險(xiǎn)往往都是從最不起眼的地方開始的。在這里,我先說一下我之前在用MongoDB時(shí)遇到的問題。這類問題同樣會出現(xiàn)在這種分頁方式上。
當(dāng)時(shí),我需要對于MongoDB中的數(shù)據(jù)進(jìn)行處理,每次處理一批,也相當(dāng)于是按頁來操作數(shù)據(jù)啦。這個(gè)沒啥難度,直接使用API中的find + skip + limit就可以輕易搞定。迅速把程序?qū)懲曛缶烷_始拿產(chǎn)品庫開搞了。剛開始一切正常,可過了沒多久,就發(fā)現(xiàn)整個(gè)程序的性能下降了。進(jìn)入Mongo一查,發(fā)現(xiàn)是Table Scan。哇,那個(gè)collection中有上千萬的數(shù)據(jù)啊!
此處略去3000字。
總之,問題最后解決了,程序又運(yùn)行如飛。而解決之道很簡單:只用find + limit,不再使用skip(原因自己想)。只不過在find中加了一個(gè)條件:上一批的最后一個(gè)document的_id。整個(gè)代碼形似(groovy代碼):
if (docId) { batch = collection.find(["_id": ["$gt": docId]] as Document).limit(BATCH_SIZE) } else { batch = collection.find().limit(BATCH_SIZE) } docId = batch[-1]["_id"]
它的原理很簡單,其實(shí)就是利用可以利用的index來加速分頁。這種思想跟今天看到的文章的思路如出一轍,不再使用offset,尋找能達(dá)到同樣效果的index,用它來助力搜索。因此,文中給出的方案跟上面的代碼類似:
SELECT ... FROM ... WHERE ... AND id < ?last_seen_id ORDER BY id DESC FETCH FIRST 10 ROWS ONLY
這種分頁方式被稱為“seek method”,其中的id被稱為“seek predicate”。典型的seek predicate還可以是日期。需要提醒的是,seek predicate上需要有index才有意義,而且它可以有多列!采用這種方式的分頁可以避免上述分頁的潛在危險(xiǎn):當(dāng)頁數(shù)達(dá)到一定量之后,分頁速度會嚴(yán)重下降。
關(guān)于seek method,還可以參考下面的文章:
https://blog.jooq.org/2013/10...
http://use-the-index-luke.com...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/18948.html
摘要:前兩篇已經(jīng)構(gòu)建了標(biāo)準(zhǔn)工程實(shí)例,也整合了實(shí)現(xiàn)了簡單數(shù)據(jù)庫訪問,本篇主要更深入的學(xué)習(xí)下,實(shí)現(xiàn)較為完整的數(shù)據(jù)庫的標(biāo)準(zhǔn)服務(wù)。到這里,最復(fù)雜的數(shù)據(jù)訪問基本就算編寫完了。 前兩篇已經(jīng)構(gòu)建了RESTful API標(biāo)準(zhǔn)工程實(shí)例,也整合了MyBatis實(shí)現(xiàn)了簡單數(shù)據(jù)庫訪問,本篇主要更深入的學(xué)習(xí)下,實(shí)現(xiàn)較為完整的數(shù)據(jù)庫CRUD的標(biāo)準(zhǔn)服務(wù)。 首先看下要實(shí)現(xiàn)的效果吧,完成下面截圖部分的API,除了CRUD之外...
摘要:虛擬機(jī)讀取其他進(jìn)程的數(shù)據(jù)對象的方法可以運(yùn)行平臺上的其他程序該方法產(chǎn)生一個(gè)對象對象代表由該程序啟動啟動的子進(jìn)程類提供如下三個(gè)方法用于和其子進(jìn)程通信獲取子進(jìn)程的錯(cuò)誤流獲取子進(jìn)程的輸入流獲取子進(jìn)程的輸出流這里的輸入流輸出流容易混淆從程序的角度思考 Java虛擬機(jī)讀取其他進(jìn)程的數(shù)據(jù) Runtime對象的exec方法可以運(yùn)行平臺上的其他程序,該方法產(chǎn)生一個(gè)Process對象,Process對象...
摘要:初始化的過程上一篇其實(shí)并未完全分析完,這回接著來。層的函數(shù)中,最后還有的調(diào)用,走的是層的。結(jié)構(gòu)體如下的和,以及,其余是狀態(tài)及的內(nèi)容。整個(gè)過程是個(gè)異步的過程,并不阻塞。至于的東西,都是在層創(chuàng)建并填充的。 初始化的過程上一篇其實(shí)并未完全分析完,這回接著來。java層的initPlayer函數(shù)中,最后還有native_setup的調(diào)用,走的是c層的IjkMediaPlayer_native_...
摘要:前言對于前后端分離大家可能在網(wǎng)上可以找到很多的文章。但是,我們今天分享的文章的英文我們的老師對于前后端的分離問題的多年工作經(jīng)驗(yàn)的總結(jié)。今天,我們把這些經(jīng)驗(yàn)總結(jié)知識點(diǎn)分享給大家,希望可以幫助到大家。添加開啟黑白名單,任選其一。 前言 對于前后端分離大家可能在網(wǎng)上可以找到很多的文章。但是,我們今天分享的文章的英文我們的老師對于前后端的分離問題的多年工作經(jīng)驗(yàn)的總結(jié)。今天,我們把這些經(jīng)驗(yàn)總結(jié)知...
閱讀 1716·2023-04-26 01:02
閱讀 4880·2021-11-24 09:39
閱讀 1815·2019-08-30 15:44
閱讀 2901·2019-08-30 11:10
閱讀 1795·2019-08-30 10:49
閱讀 993·2019-08-29 17:06
閱讀 619·2019-08-29 16:15
閱讀 910·2019-08-29 15:17