程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> Mysql limit 優化,百萬至萬萬級疾速分頁 復合索引的援用並運用於輕量級框架

Mysql limit 優化,百萬至萬萬級疾速分頁 復合索引的援用並運用於輕量級框架

編輯:MySQL綜合教程

Mysql limit 優化,百萬至萬萬級疾速分頁 復合索引的援用並運用於輕量級框架。本站提示廣大學習愛好者:(Mysql limit 優化,百萬至萬萬級疾速分頁 復合索引的援用並運用於輕量級框架)文章只能為提供參考,不一定能成為您想要的結果。以下是Mysql limit 優化,百萬至萬萬級疾速分頁 復合索引的援用並運用於輕量級框架正文


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做索引的成果。可是成績龐雜那末一點點,就完了。看上面的語句

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.vhao.net是一樣的思緒。思緒以下:

建一個索引表: 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;
很快了。根本上0.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 主鍵!

完善處理了分頁成績了。可以疾速前往id就有願望優化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應當也很輕易敷衍。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved