国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Mysql - Mysql limit 優化,百萬至千萬級快速分頁 復合索引的引用并應用于輕量級框架

Mysql limit 優化,百萬至千萬級快速分頁 復合索引的引用并應用于輕量級框架

2019-11-19 15:03MYSQL教程網 Mysql

MySql 性能到底能有多高?用了php半年多,真正如此深入的去思考這個問題還是從前天開始。有過痛苦有過絕望,到現在充滿信心!

MySql 這個數據庫絕對是適合dba級的高手去玩的,一般做一點1萬篇新聞的小型系統怎么寫都可以,用xx框架可以實現快速開發。可是數據量到了10萬,百萬至千萬,他的性能還能那么高嗎?一點小小的失誤,可能造成整個系統的改寫,甚至更本系統無法正常運行!好了,不那么多廢話了。用事實說話,看例子: 

數據表 collect ( id, title ,info ,vtype) 就這4個字段,其中 title 用定長,info 用text, id 
是逐漸,vtype是tinyint,vtype是索引。這是一個基本的新聞系統的簡單模型。現在往里面填充數據,填充10萬篇新聞。 

最后collect 為 10萬條記錄,數據庫表占用硬盤1.6G。OK ,看下面這條sql語句: 

select id,title from collect limit 1000,10; 很快;基本上0.01秒就OK,再看下面的 

select id,title from collect limit 90000,10; 從9萬條開始分頁,結果? 

8-9秒完成,my god 哪出問題了????其實要優化這條數據,網上找得到答案。看下面一條語句: 

select id from collect order by id limit 90000,10; 很快,0.04秒就OK。 
為什么?因為用了id主鍵做索引當然快。網上的改法是: 

select id,title from collect where id>=(select id from collect order by id 
limit 90000,1) limit 10; 

這就是用了id做索引的結果??墒菃栴}復雜那么一點點,就完了??聪旅娴恼Z句 

select id from collect where vtype=1 order by id limit 90000,10; 
很慢,用了8-9秒! 

到了這里我相信很多人會和我一樣,有崩潰感覺!vtype 做了索引了???怎么會慢呢?vtype做了索引是不錯,你直接 select id from 
collect where vtype=1 limit 1000,10; 
是很快的,基本上0.05秒,可是提高90倍,從9萬開始,那就是0.05*90=4.5秒的速度了。和測試結果8-9秒到了一個數量級。從這里開始有人提出了分表的思路,這個和discuz 
論壇是一樣的思路。思路如下: 

建一個索引表: t (id,title,vtype) 并設置成定長,然后做分頁,分頁出結果再到 collect 里面去找info 。 
是否可行呢?實驗下就知道了。 

10萬條記錄到 t(id,title,vtype) 里,數據表大小20M左右。用 

select id from t where vtype=1 order by id limit 90000,10; 
很快了?;旧?.1-0.2秒可以跑完。為什么會這樣呢?我猜想是因為collect 數據太多,所以分頁要跑很長的路。limit 
完全和數據表的大小有關的。其實這樣做還是全表掃描,只是因為數據量小,只有10萬才快。OK, 來個瘋狂的實驗,加到100萬條,測試性能。 

加了10倍的數據,馬上t表就到了200多M,而且是定長。還是剛才的查詢語句,時間是0.1-0.2秒完成!分表性能沒問題?錯!因為我們的limit還是9萬,所以快。給個大的,90萬開始 

select id from t where vtype=1 order by id limit 900000,10; 看看結果,時間是1-2秒! 

why ?? 分表了時間還是這么長,非常之郁悶!有人說定長會提高limit的性能,開始我也以為,因為一條記錄的長度是固定的,mysql 
應該可以算出90萬的位置才對?。?可是我們高估了mysql 的智能,他不是商務數據庫,事實證明定長和非定長對limit影響不大? 怪不得有人說 
discuz到了100萬條記錄就會很慢,我相信這是真的,這個和數據庫設計有關! 

難道MySQL 無法突破100萬的限制嗎???到了100萬的分頁就真的到了極限??? 

答案是: NO !!!! 
為什么突破不了100萬是因為不會設計mysql造成的。下面介紹非分表法,來個瘋狂的測試!一張表搞定100萬記錄,并且10G 
數據庫,如何快速分頁! 

好了,我們的測試又回到 collect表,開始測試結論是: 
30萬數據,用分表法可行,超過30萬他的速度會慢道你無法忍受!當然如果用分表+我這種方法,那是絕對完美的。但是用了我這種方法后,不用分表也可以完美解決! 

答案就是:復合索引! 有一次設計mysql索引的時候,無意中發現索引名字可以任取,可以選擇幾個字段進來,這有什么用呢?開始的select id from 
collect order by id limit 90000,10; 這么快就是因為走了索引,可是如果加了where 就不走索引了。抱著試試看的想法加了 
search(vtype,id) 這樣的索引。然后測試 

select id from collect where vtype=1 limit 90000,10; 非???!0.04秒完成! 

再測試: select id ,title from collect where vtype=1 limit 90000,10; 
非常遺憾,8-9秒,沒走search索引! 

再測試:search(id,vtype),還是select id 這個語句,也非常遺憾,0.5秒。 

綜上:如果對于有where 條件,又想走索引用limit的,必須設計一個索引,將where 
放第一位,limit用到的主鍵放第2位,而且只能select 主鍵! 

完美解決了分頁問題了??梢钥焖俜祷豬d就有希望優化limit , 按這樣的邏輯,百萬級的limit 應該在0.0x秒就可以分完。看來mysql 
語句的優化和索引時非常重要的! 

好了,回到原題,如何將上面的研究成功快速應用于開發呢?如果用復合查詢,我的輕量級框架就沒的用了。分頁字符串還得自己寫,那多麻煩?這里再看一個例子,思路就出來了: 

select * from collect where id in (9000,12,50,7000); 竟然 0秒就可以查完! 

mygod ,mysql 的索引竟然對于in語句同樣有效!看來網上說in無法用索引是錯誤的! 

有了這個結論,就可以很簡單的應用于輕量級框架了: 

代碼如下: 

復制代碼代碼如下:


$db=dblink(); 
$db->pagesize=20; 

$sql="select id from collect where vtype=$vtype"; 

$db->execute($sql); 
$strpage=$db->strpage(); 
//將分頁字符串保存在臨時變量,方便輸出 
while($rs=$db->fetch_array()){ 
$strid.=$rs['id'].','; 

$strid=substr($strid,0,strlen($strid)-1); 
//構造出id字符串 
$db->pagesize=0; 
//很關鍵,在不注銷類的情況下,將分頁清空,這樣只需要用一次數據庫連接,不需要再開; 
$db->execute("select 
id,title,url,sTime,gTime,vtype,tag from collect where id in ($strid)"); 

<?php while($rs=$db->fetch_array()): ?> 
<tr> 
<td> <?php echo $rs['id'];?></td> 
<td> <?php echo $rs['url'];?></td> 
<td> <?php echo $rs['sTime'];?></td> 
<td> <?php echo $rs['gTime'];?></td> 
<td> <?php echo $rs['vtype'];?></td> 
<td> <a href="?act=show&id=<?php echo $rs['id'];?>" 
target="_blank"><?php echo $rs['title'];?></a></td> 
<td> <?php echo 
$rs['tag'];?></td> 
</tr> 
<?php endwhile; 
?> 
</table> 
<?php 
echo $strpage; 


通過簡單的變換,其實思路很簡單:1)通過優化索引,找出id,并拼成 "123,90000,12000" 這樣的字符串。2)第2次查詢找出結果。 

小小的索引+一點點的改動就使mysql 可以支持百萬甚至千萬級的高效分頁! 

通過這里的例子,我反思了一點:對于大型系統,PHP千萬不能用框架,尤其是那種連sql語句都看不到的框架!因為開始對于我的輕量級框架都差點崩潰!只適合小型應用的快速開發,對于ERP,OA,大型網站,數據層包括邏輯層的東西都不能用框架。如果程序員失去了對sql語句的把控,那項目的風險將會成幾何級數增加!尤其是用mysql 
的時候,mysql 一定需要專業的dba 才可以發揮他的最佳性能。一個索引所造成的性能差別可能是上千倍! 

PS: 
經過實際測試,到了100萬的數據,160萬數據,15G表,190M索引,就算走索引,limit都得0.49秒。所以分頁最好別讓別人看到10萬條以后的數據,要不然會很慢!就算用索引。經過這樣的優化,mysql到了百萬級分頁是個極限!但有這樣的成績已經很不錯,如果你是用sqlserver肯定卡死!而160萬的數據用 
id in (str) 很快,基本還是0秒。如果這樣,千萬級的數據,mysql應該也很容易應付。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 欧美午夜精品久久久 | 国产黄色在线观看 | 日韩中文字幕视频 | 国产精品剧情一区二区三区 | 亚洲成人精品在线 | 在线免费观看中文字幕 | 国产精品成人在线 | 国产一区二区精品久久岳 | 九色 在线| 欧美日一区二区 | 午夜在线小视频 | 91视视频在线观看入口直接观看 | 久久综合2019| 中文字幕久久精品 | 亚洲免费在线看 | 中国大陆高清aⅴ毛片 | 视频在线一区二区 | 久久伊人国产 | 国产一区二区三区久久 | 国产精品美女 | 亚洲视频观看 | 一区二区三区高清 | 在线视频 中文字幕 | 亚洲a网| 一本大道久久a久久精二百 国产欧美视频一区二区 | 国产成人精品一区二区三区四区 | 91精品久久久久久久久 | a级黄色在线观看 | 久热国产视频 | 日韩精品1区 | 亚洲成人在线观看视频 | 国产精品a久久久久 | 中文字幕一区二区三区四区不卡 | 欧美激情二区 | 久久久国产99久久国产一 | 国产在线在线 | 在线精品国产 | 国产精品免费视频一区二区三区 | 久久国产一区二区 | 国产精品一区二区三区免费视频 | 人人做人人澡人人爽欧美 |