分頁查詢的sql語句,多條sql怎么分頁

大家好,感謝邀請,今天來為大家分享一下分頁查詢的sql語句的問題,以及和多條sql怎么分頁的一些困惑,大家要是還不太明白的話,也沒有關系,因為接下來將為大家分享,希望可...
大家好,感謝邀請,今天來為大家分享一下分頁查詢的sql語句的問題,以及和多條sql怎么分頁的一些困惑,大家要是還不太明白的話,也沒有關系,因為接下來將為大家分享,希望可以幫助到大家,解決大家的問題,下面就開始吧!
mysql數據庫,分表后,怎么進行分頁查詢Mysql分庫分表方案
Mysql分庫分表方案
1.為什么要分表:
當一張表的數據達到幾千萬時,你查詢一次所花的時間會變多,如果有聯合查詢的話,我想有可能會死在那兒了。分表的目的就在于此,減小數據庫的負擔,縮短查詢時間。
mysql中有一種機制是表鎖定和行鎖定,是為了保證數據的完整性。表鎖定表示你們都不能對這張表進行操作,必須等我對表操作完才行。行鎖定也一樣,別的sql必須等我對這條數據操作完了,才能對這條數據進行操作。
2.mysqlproxy:amoeba
做mysql集群,利用amoeba。
從上層的java程序來講,不需要知道主服務器和從服務器的來源,即主從數據庫服務器對于上層來講是透明的。可以通過amoeba來配置。
3.大數據量并且訪問頻繁的表,將其分為若干個表
比如對于某網站平臺的數據庫表-公司表,數據量很大,這種能預估出來的大數據量表,我們就事先分出個N個表,這個N是多少,根據實際情況而定。
某網站現在的數據量至多是5000萬條,可以設計每張表容納的數據量是500萬條,也就是拆分成10張表,
那么如何判斷某張表的數據是否容量已滿呢?可以在程序段對于要新增數據的表,在插入前先做統計表記錄數量的操作,當<500萬條數據,就直接插入,當已經到達閥值,可以在程序段新創建數據庫表(或者已經事先創建好),再執行插入操作。
4.利用merge存儲引擎來實現分表
如果要把已有的大數據量表分開比較痛苦,最痛苦的事就是改代碼,因為程序里面的sql語句已經寫好了。用merge存儲引擎來實現分表,這種方法比較適合.
如何進行分頁設計可以讓sql更高效
高效的分頁設計就是只包含上下頁,而沒有用頁數的統計,也沒有最后一頁的設計。可以采用下拉加載這種設計方案,或者是瀑布流,用戶很少會有翻頁到最后一頁的需求,就像搜索引擎一樣,基本大家查看的都是前三頁的內容,如果沒有找到,一般都會替換關鍵詞進行查找。這就說明,用戶只關心自己感興趣的你提供更多的內容,如果用戶不感興趣,那就是沒有任何意義。
因此,我們說到高效分頁設計,其實考察的還是內容的排序設計,如何把用戶感興趣的內容排列在前面,這樣的排序才有價值,用戶才滿意,而這些正是現在的抖音,今日頭條的推薦算法。所以說,在這方面,今日頭條的算法還是很強大的。
最后,我們說回sql,進行分頁查詢的時候,大部分我們使用的是limit進行限定分頁,但是,真的當數據量很大的時候,我們就需要對查詢進行條件限定,因為對于limit100000000000,10
這樣的查詢語句,就是獲取很大數據后的10條數據,查詢效率會很低,這個時候如果我們加上限定條件whereid>1000000000000limit10,這樣查詢的效果就會非常快,當然,這里需要滿足我們的數據是連續的。
MySQL如何優化大分頁查詢
很多應用往往只展示最新或最熱門的幾條記錄,但為了舊記錄仍然可訪問,所以就需要個分頁的導航欄。然而,如何通過MySQL更好的實現分頁,始終是比較令人頭疼的問題。雖然沒有拿來就能用的解決辦法,但了解數據庫的底層或多或少有助于優化分頁查詢。
我們先從一個常用但性能很差的查詢來看一看。
SELECT*
FROMcity
ORDERBYidDESC
LIMIT0,15
這個查詢耗時0.00sec。So,這個查詢有什么問題呢?實際上,這個查詢語句和參數都沒有問題,因為它用到了下面表的主鍵,而且只讀取15條記錄。
CREATETABLEcity(
idint(10)unsignedNOTNULLAUTO_INCREMENT,
cityvarchar(128)NOTNULL,
PRIMARYKEY(id)
)ENGINE=InnoDB;
真正的問題在于offset(分頁偏移量)很大的時候,像下面這樣:
SELECT*
FROMcity
ORDERBYidDESC
LIMIT100000,15;
上面的查詢在有2M行記錄時需要0.22sec,通過EXPLAIN查看SQL的執行計劃可以發現該SQL檢索了100015行,但最后只需要15行。大的分頁偏移量會增加使用的數據,MySQL會將大量最終不會使用的數據加載到內存中。就算我們假設大部分網站的用戶只訪問前幾頁數據,但少量的大的分頁偏移量的請求也會對整個系統造成危害。Facebook意識到了這一點,但Facebook并沒有為了每秒可以處理更多的請求而去優化數據庫,而是將重心放在將請求響應時間的方差變小。
對于分頁請求,還有一個信息也很重要,就是總共的記錄數。我們可以通過下面的查詢很容易的獲取總的記錄數。
SELECTCOUNT(*)
FROMcity;
然而,上面的SQL在采用InnoDB為存儲引擎時需要耗費9.28sec。一個不正確的優化是采用SQL_CALC_FOUND_ROWS,SQL_CALC_FOUND_ROWS可以在能夠在分頁查詢時事先準備好符合條件的記錄數,隨后只要執行一句selectFOUND_ROWS();就能獲得總記錄數。但是在大多數情況下,查詢語句簡短并不意味著性能的提高。不幸的是,這種分頁查詢方式在許多主流框架中都有用到,下面看看這個語句的查詢性能。
SELECTSQL_CALC_FOUND_ROWS*
FROMcity
ORDERBYidDESC
LIMIT100000,15;
這個語句耗時20.02sec,是上一個的兩倍。事實證明使用SQL_CALC_FOUND_ROWS做分頁是很糟糕的想法。
下面來看看到底如何優化。文章分為兩部分,第一部分是如何獲取記錄的總數目,第二部分是獲取真正的記錄。
高效的計算行數
如果采用的引擎是MyISAM,可以直接執行COUNT(*)去獲取行數即可。相似的,在堆表中也會將行數存儲到表的元信息中。但如果引擎是InnoDB情況就會復雜一些,因為InnoDB不保存表的具體行數。
我們可以將行數緩存起來,然后可以通過一個守護進程定期更新或者用戶的某些操作導致緩存失效時,執行下面的語句:
SELECTCOUNT(*)
FROMcity
USEINDEX(PRIMARY);
獲取記錄
下面進入這篇文章最重要的部分,獲取分頁要展示的記錄。上面已經說過了,大的偏移量會影響性能,所以我們要重寫查詢語句。為了演示,我們創建一個新的表“news”,按照時事性排序(最新發布的在最前面),實現一個高性能的分頁。為了簡單,我們就假設最新發布的新聞的Id也是最大的。
CREATETABLEnews(
idINTUNSIGNEDPRIMARYKEYAUTO_INCREMENT,
titleVARCHAR(128)NOTNULL
)ENGINE=InnoDB;
一個比較高效的方式是基于用戶展示的最后一個新聞Id。查詢下一頁的語句如下,需要傳入當前頁面展示的最后一個Id。
SELECT*
FROMnewsWHEREid<$last_id
ORDERBYidDESC
LIMIT$perpage
查詢上一頁的語句類似,只不過需要傳入當前頁的第一個Id,并且要逆序。
SELECT*
FROMnewsWHEREid>$last_id
ORDERBYidASC
LIMIT$perpage
上面的查詢方式適合實現簡易的分頁,即不顯示具體的頁數導航,只顯示“上一頁”和“下一頁”,例如博客中頁腳顯示“上一頁”,“下一頁”的按鈕。但如果要實現真正的頁面導航還是很難的,下面看看另一種方式。
SELECTid
FROM(
SELECTid,((@cnt:=@cnt+1)+$perpage-1)%$perpagecnt
FROMnews
JOIN(SELECT@cnt:=0)T
WHEREid<$last_id
ORDERBYidDESC
LIMIT$perpage*$buttons
)C
WHEREcnt=0;
通過上面的語句可以為每一個分頁的按鈕計算出一個offset對應的id。這種方法還有一個好處。假設,網站上正在發布一片新的文章,那么所有文章的位置都會往后移一位,所以如果用戶在發布文章時換頁,那么他會看見一篇文章兩次。如果固定了每個按鈕的offsetId,這個問題就迎刃而解了。MarkCallaghan發表過一篇類似的博客,利用了組合索引和兩個位置變量,但是基本思想是一致的。
如果表中的記錄很少被刪除、修改,還可以將記錄對應的頁碼存儲到表中,并在該列上創建合適的索引。采用這種方式,當新增一個記錄的時候,需要執行下面的查詢重新生成對應的頁號。
SETp:=0;
UPDATEnewsSETpage=CEIL((p:=p+1)/$perpage)ORDERBYidDESC;
當然,也可以新增一個專用于分頁的表,可以用個后臺程序來維護。
UPDATEpaginationT
JOIN(
SELECTid,CEIL((p:=p+1)/$perpage)page
FROMnews
ORDERBYid
)C
ONC.id=T.id
SETT.page=C.page;
現在想獲取任意一頁的元素就很簡單了:
SELECT*
FROMnewsA
JOINpaginationBONA.id=B.ID
WHEREpage=$offset;
還有另外一種與上種方法比較相似的方法來做分頁,這種方式比較試用于數據集相對小,并且沒有可用的索引的情況下—比如處理搜索結果時。在一個普通的服務器上執行下面的查詢,當有2M條記錄時,要耗費2sec左右。這種方式比較簡單,創建一個用來存儲所有Id的臨時表即可(這也是最耗費性能的地方)。
CREATETEMPORARYTABLE_tmp(KEYSORT(random))
SELECTid,FLOOR(RAND()*0x8000000)random
FROMcity;
ALTERTABLE_tmpADDOFFSETINTUNSIGNEDPRIMARYKEYAUTO_INCREMENT,DROPINDEXSORT,ORDERBYrandom;
接下來就可以向下面一樣執行分頁查詢了。
SELECT*
FROM_tmp
WHEREOFFSET>=$offset
ORDERBYOFFSET
LIMIT$perpage;
簡單來說,對于分頁的優化就是。。。避免數據量大時掃描過多的記錄。
如何使用mybatis實現分頁
1、親Mybatis是自己寫Sql語句啊,和Hibernate不一樣。
2、如何知道上面的,你還要知道MySql有一個分頁語句叫limit,如:limit(1,10);前面一個參數是起始未知,后面一個是查詢多少個。
3、Oracle的分頁方法是嵌套子查詢,需要用到rownum這個屬性SqlServer是Top。分頁例子:Oracleselect*from(selectemp.*,rownumrnfromempwhererownum<9)wherern>3;MySqlselect*fromemplimitstartIndex,maxNum
高效的mysql分頁方法及原理
一,最常見MYSQL最基本的分頁方式:
select*fromcontentorderbyiddesclimit0,10
在中小數據量的情況下,這樣的SQL足夠用了,唯一需要注意的問題就是確保使用了索引。隨著數據量的增加,頁數會越來越多,查看后幾頁的SQL就可能類似:
select*fromcontentorderbyiddesclimit10000,10
就是越往后分頁,LIMIT語句的偏移量就會越大,速度也會明顯變慢。
此時,可以通過2種方式:
一,子查詢的分頁方式來提高分頁效率,飄易用的SQL語句如下:
SELECT*FROMcontentWHEREid>(SELECTidFROMcontentORDERBYiddescLIMIT".($page-1)*$pagesize.",1)ORDERBYiddescLIMIT$pagesize
為什么會這樣呢?因為子查詢是在索引上完成的,而普通的查詢時在數據文件上完成的,通常來說,索引文件要比數據文件小得多,所以操作起來也會更有效率。(via)通過explainSQL語句發現:子查詢使用了索引!
idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra
1PRIMARYcontentrangePRIMARYPRIMARY4NULL6264Usingwhere
2SUBQUERYcontentindexNULLPRIMARY4NULL27085Using
如何實現分頁查詢
回答如下:分頁查詢可以通過以下步驟實現:
1.定義每頁顯示的記錄數,如每頁顯示10條記錄。
2.定義查詢的起始位置,如第1頁從0開始查詢,第2頁從10開始查詢。
3.執行查詢語句時,加入limit關鍵字,如查詢第1頁的語句為:select*fromtablelimit0,10。
4.查詢結果返回后,根據總記錄數和每頁顯示的記錄數,計算出總頁數。
5.在頁面上顯示查詢結果,并提供翻頁功能,如上一頁、下一頁、跳轉到指定頁等。
6.根據用戶的操作,重新計算起始位置,并重新執行查詢語句,返回新的查詢結果。
需要注意的是,分頁查詢可能會影響查詢性能,因此需要合理設置每頁顯示的記錄數,避免一次查詢返回過多的記錄。同時,可以通過索引優化等手段提高查詢效率。
關于本次分頁查詢的sql語句和多條sql怎么分頁的問題分享到這里就結束了,如果解決了您的問題,我們非常高興。
本文鏈接:http://www.resource-tj.com/kaifa/2167.html