mysql的limit和or_面试官:谈谈MySQL的limit用法、逻辑分页和物理分页
來(lái)源:blog.csdn.net/lvoelife/article/details/81943070
物理分頁(yè)為什么用limit
在講解limit之間,我們先說(shuō)說(shuō)分頁(yè)的事情。
分頁(yè)有邏輯分頁(yè)和物理分頁(yè),就像刪除有邏輯刪除和物理刪除。邏輯刪除就是改變數(shù)據(jù)庫(kù)的狀態(tài),物理刪除就是直接刪除數(shù)據(jù)庫(kù)的記錄,而邏輯刪除只是改變?cè)摂?shù)據(jù)庫(kù)的狀態(tài)。例如
同理,邏輯分頁(yè)和物理分頁(yè)是有區(qū)別的
為什么邏輯分頁(yè)占用較大的內(nèi)存空間,比如我有一張表,表的信息是:
--?----------------------------
--?Table?structure?for?vote_record_memory
--?----------------------------
DROP?TABLE?IF?EXISTS?`vote_record_memory`;
CREATE?TABLE?`vote_record_memory`?(
`id`?int(11)?NOT?NULL?AUTO_INCREMENT,
`user_id`?varchar(20)?NOT?NULL,
`vote_id`?int(11)?NOT?NULL,
`group_id`?int(11)?NOT?NULL,
`create_time`?datetime?NOT?NULL,
PRIMARY?KEY?(`id`),
KEY?`index_id`?(`user_id`)?USING?HASH
)?ENGINE=MEMORY?AUTO_INCREMENT=3000001?DEFAULT?CHARSET=utf8;
向該表中插入300萬(wàn)條數(shù)據(jù)后,再轉(zhuǎn)儲(chǔ)到桌面,查看轉(zhuǎn)儲(chǔ)后的SQL文件的屬性:
這是多么龐大的數(shù)據(jù),占用的內(nèi)存多么可怕,為什么我們?cè)龠x用數(shù)據(jù)庫(kù)。這也是我們使用云服務(wù)器時(shí),設(shè)定mysql的存儲(chǔ)空間的大小。
我們一般不推薦使用邏輯分頁(yè),而使用物理分頁(yè)。在使用物理分頁(yè)的時(shí)候,就要考慮到limit的用法。
解釋limit
limit X,Y ,跳過(guò)前X條數(shù)據(jù),讀取Y條數(shù)據(jù)
X表示第一個(gè)返回記錄行的偏移量,Y表示返回記錄行的最大數(shù)目
如果X為0的話,即 limit 0, Y,相當(dāng)于limit Y、
通過(guò)業(yè)務(wù)分析limit
我有一張工資表,只顯示最新的_前兩條記錄_,同時(shí)進(jìn)行員工姓名和工資提成備注查詢
SELECT
cue.real_name?empName,
zs.push_money?AS?pushMoney,
zs.push_money_note?AS?pushMoneyNote,
zs.create_datetime?AS?createTime
FROM
zq_salary?zs??//主表
LEFT?JOIN?core_user_ext?cue?ON?cue.id?=?zs.user_id???//從表?on之后是從表的條件
WHERE
zs.is_deleted?=?0
AND?(
cue.real_name?LIKE?'%李%'
OR?zs.push_money_note?LIKE?'%測(cè)%'
)
ORDER?BY
zs.create_datetime?DESC
LIMIT?2;
就相當(dāng)于
ORDER?BY
zs.create_datetime?DESC
LIMIT?0,2;
limit的效率問(wèn)題
我有一個(gè)需求,就是從vote_record_memory表中查出3600000到3800000的數(shù)據(jù),此時(shí)在id上加個(gè)索引,索引的類型是Normal,索引的方法是BTREE,分別用兩種方法查詢
--?方法1
SELECT?*?FROM?vote_record_memory?vrm??LIMIT?3600000,20000?;
--?方法2
SELECT?*?FROM?vote_record_memory?vrm?WHERE?vrm.id?>=?3600000?LIMIT?20000
你會(huì)發(fā)現(xiàn),方法2的執(zhí)行效率遠(yuǎn)比方法1的執(zhí)行效率高,幾乎是方法1的九分之一的時(shí)間。
為什么方法1的效率低,而方法二的效率高呢?
分析一、
因?yàn)樵诜椒?中,我們使用的單純的limit。limit隨著行偏移量的增大,當(dāng)大到一定程度后,會(huì)出現(xiàn)效率下降。而方法2用上索引加where和limit,性能基本穩(wěn)定,受偏移量和行數(shù)的影響不大。
分析二、
我們用explain來(lái)分析
可見(jiàn),limit語(yǔ)句的執(zhí)行效率未必很高,因?yàn)闀?huì)進(jìn)行全表掃描,這就是為什么方法1掃描的的行數(shù)是400萬(wàn)行的原因。方法2的掃描行數(shù)是47945行,這也是為什么方法2執(zhí)行效率高的原因。我們盡量避免全表掃描查詢,尤其是數(shù)據(jù)非常龐大,這張表僅有400萬(wàn)條數(shù)據(jù),方法1和方法就有這么大差距,可想而知上千萬(wàn)條的數(shù)據(jù)呢。
能用索引的盡量使用索引,type至少達(dá)到range級(jí)別_,這不是我說(shuō)的,這是阿里巴巴開(kāi)發(fā)手冊(cè)的5.2.8中要求的_
我不用索引查詢到的結(jié)果和返回的時(shí)間和方法1的時(shí)間差不多:
SELECT?*?FROM?vote_record_memory?vrm?WHERE?vrm.id?>=?3600000?LIMIT
20000 受影響的行: 0 時(shí)間: 0.196s
這也就是我們?yōu)槭裁幢M量使用索引的原因。mysql索引方法一般有BTREE索引和HASH索引,hash索引的效率比BTREE索引的效率高,但我們經(jīng)常使用BTREE索引,而不是hash索引。因?yàn)樽钪匾囊稽c(diǎn)就是:Hash索引僅僅能滿足”=”,”IN”和”<=>”查詢,不能使用范圍查詢。
如果是范圍查詢,我們?yōu)槭裁从肂TREE索引的原因。BTREE索引就是二叉樹(shù)索引,學(xué)過(guò)數(shù)據(jù)結(jié)構(gòu)的應(yīng)該都清楚,這里就不贅述了。
limit物理分頁(yè)
我們都知道limit一般有兩個(gè)參數(shù),X和Y,X表示跳過(guò)X個(gè)數(shù)據(jù),讀取Y個(gè)數(shù)據(jù),我們就此來(lái)查詢數(shù)據(jù)
如果是SQL語(yǔ)句來(lái)進(jìn)行分頁(yè)的話,我們可以看到的是:
--?首頁(yè)
SELECT?*?from?vote_record_memory?LIMIT?0,20;
--?第二頁(yè)
SELECT?*?from?vote_record_memory?LIMIT?20,20;
--?第三頁(yè)
SELECT?*?from?vote_record_memory?LIMIT?40,20;
--?第四頁(yè)
SELECT?*?from?vote_record_memory?LIMIT?60,20;
--?n頁(yè)
SELECT?*?from?vote_record_memory?LIMIT?(n-1)*20,20;
因而,如果是用java的話,我們就可以寫(xiě)一個(gè)方法,有兩個(gè)參數(shù),一個(gè)是頁(yè)數(shù),一個(gè)每頁(yè)顯示的行數(shù)
/**
*?@description??????????簡(jiǎn)單的模擬分頁(yè)雛形
*?@author???????????????zby
*?@param?currentPage????當(dāng)前頁(yè)
*?@param?lines??????????每頁(yè)顯示的多少條
*?@return???????????????數(shù)據(jù)的集合
*/
public?List?listObjects(int?currentPage,?int?lines)?{
String?sql?=?"SELECT?*?from?vote_record_memory?LIMIT?"?+?(currentPage?-?1)?*?lines?+?","?+?lines;
return?null;
}
↓↓↓↓點(diǎn)擊下方獲取源碼和教程↓↓↓↓
總結(jié)
以上是生活随笔為你收集整理的mysql的limit和or_面试官:谈谈MySQL的limit用法、逻辑分页和物理分页的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 智能穿戴板块股票一览 以下几家公司要多看
- 下一篇: 口头挂失有效期为几天