測(cè)試環(huán)境:
先讓我們熟悉下基本的sql語(yǔ)句,來(lái)查看下我們將要測(cè)試表的基本信息
| use infomation_schemaSELECT * FROM TABLES WHERE TABLE_SCHEMA = ‘dbname' AND TABLE_NAME = ‘product' |
查詢(xún)結(jié)果:

從上圖中我們可以看到表的基本信息:
表行數(shù):866633
平均每行的數(shù)據(jù)長(zhǎng)度:5133字節(jié)
單表大小:4448700632字節(jié)
關(guān)于行和表大小的單位都是字節(jié),我們經(jīng)過(guò)計(jì)算可以知道
平均行長(zhǎng)度:大約5k
單表總大小:4.1g
表中字段各種類(lèi)型都有varchar、datetime、text等,id字段為主鍵
測(cè)試實(shí)驗(yàn)
1. 直接用limit start, count分頁(yè)語(yǔ)句, 也是我程序中用的方法:
select * from product limit start, count
當(dāng)起始頁(yè)較小時(shí),查詢(xún)沒(méi)有性能問(wèn)題,我們分別看下從10, 100, 1000, 10000開(kāi)始分頁(yè)的執(zhí)行時(shí)間(每頁(yè)取20條), 如下:
| select * from product limit 10, 20 0.016秒select * from product limit 100, 20 0.016秒select * from product limit 1000, 20 0.047秒select * from product limit 10000, 20 0.094秒 |
我們已經(jīng)看出隨著起始記錄的增加,時(shí)間也隨著增大, 這說(shuō)明分頁(yè)語(yǔ)句limit跟起始頁(yè)碼是有很大關(guān)系的,那么我們把起始記錄改為40w看下(也就是記錄的一般左右) select * from product limit 400000, 20 3.229秒
再看我們?nèi)∽詈笠豁?yè)記錄的時(shí)間
select * from product limit 866613, 20 37.44秒
難怪搜索引擎抓取我們頁(yè)面的時(shí)候經(jīng)常會(huì)報(bào)超時(shí),像這種分頁(yè)最大的頁(yè)碼頁(yè)顯然這種時(shí)
間是無(wú)法忍受的。
從中我們也能總結(jié)出兩件事情:
1)limit語(yǔ)句的查詢(xún)時(shí)間與起始記錄的位置成正比
2)mysql的limit語(yǔ)句是很方便,但是對(duì)記錄很多的表并不適合直接使用。
2. 對(duì)limit分頁(yè)問(wèn)題的性能優(yōu)化方法
利用表的覆蓋索引來(lái)加速分頁(yè)查詢(xún)
我們都知道,利用了索引查詢(xún)的語(yǔ)句中如果只包含了那個(gè)索引列(覆蓋索引),那么這種情況會(huì)查詢(xún)很快。
因?yàn)槔盟饕檎矣袃?yōu)化算法,且數(shù)據(jù)就在查詢(xún)索引上面,不用再去找相關(guān)的數(shù)據(jù)地址了,這樣節(jié)省了很多時(shí)間。另外Mysql中也有相關(guān)的索引緩存,在并發(fā)高的時(shí)候利用緩存就效果更好了。
在我們的例子中,我們知道id字段是主鍵,自然就包含了默認(rèn)的主鍵索引。現(xiàn)在讓我們看看利用覆蓋索引的查詢(xún)效果如何:
這次我們之間查詢(xún)最后一頁(yè)的數(shù)據(jù)(利用覆蓋索引,只包含id列),如下:
select id from product limit 866613, 20 0.2秒
相對(duì)于查詢(xún)了所有列的37.44秒,提升了大概100多倍的速度
那么如果我們也要查詢(xún)所有列,有兩種方法,一種是id>=的形式,另一種就是利用join,看下實(shí)際情況:
新聞熱點(diǎn)
疑難解答
圖片精選