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

MySQL 百萬級分頁優化(Mysql萬萬級疾速分頁)

編輯:MySQL綜合教程

MySQL 百萬級分頁優化(Mysql萬萬級疾速分頁)。本站提示廣大學習愛好者:(MySQL 百萬級分頁優化(Mysql萬萬級疾速分頁))文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL 百萬級分頁優化(Mysql萬萬級疾速分頁)正文


以下分享一點我的經歷

普通剛開端學SQL的時刻,會如許寫

SELECT * FROM table ORDER BY id LIMIT 1000, 10;

但在數據到達百萬級的時刻,如許寫會慢逝世

SELECT * FROM table ORDER BY id LIMIT 1000000, 10;

或許消耗幾十秒

網上許多優化的辦法是如許的

SELECT * FROM table WHERE id >= (SELECT id FROM table LIMIT 1000000, 1) LIMIT 10;

是的,速度晉升到0.x秒了,看模樣還行了
可是,還不是完善的!

以下這句才是完善的!

SELECT * FROM table WHERE id BETWEEN 1000000 AND 1000010;

比下面那句,還要再快5至10倍

別的,假如須要查詢 id 不是持續的一段,最好的辦法就是先找出 id ,然後用 in 查詢

SELECT * FROM table WHERE id IN(10000, 100000, 1000000...);


再分享一點
查詢字段一較長字符串的時刻,表設計時要為該字段多加一個字段,如,存儲網址的字段
查詢的時刻,不要直接查詢字符串,效力低下,應當查詭該字串的crc32或md5

若何優化Mysql萬萬級疾速分頁

Limit 1,111 數據年夜了確切有些機能上的成績,而經由過程各類辦法給用上where id >= XX,如許用上索引的id號能夠速度上快點兒。By:jack
Mysql limit分頁慢的處理方法(Mysql limit 優化,百萬至萬萬筆記錄完成疾速分頁)

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做索引的成果。可是成績龐雜那末一點點,就完了。看上面的語句
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秒到了一個數目級。從這裡開端有人 提出了分表的思緒,這個和dis #cuz 服裝論壇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秒。所以分頁最好別讓他人
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved