總結(jié)MySQL的分頁技術(shù)

  有朋友問: MySQL的分頁似乎一直是個(gè)問題,有什么優(yōu)化方法嗎?網(wǎng)上看到網(wǎng)上推薦了一些分頁方法,但似乎不太可行,你能點(diǎn)評(píng)一下嗎?

  方法1:?直接使用數(shù)據(jù)庫提供的SQL語句

  —語句樣式: MySQL中,可用如下方法: SELECT * FROM 表名稱 LIMIT?M,N。

  —適應(yīng)場(chǎng)景: 適用于數(shù)據(jù)量較少的情況(元組百/千級(jí))。

  —原因/缺點(diǎn): 全表掃描,速度會(huì)很慢 且?有的數(shù)據(jù)庫結(jié)果集返回不穩(wěn)定(如某次返回1,2,3,另外的一次返回2,1,3)。Limit限制的是從結(jié)果集的M位置處取出N條輸出,其余拋棄。

  方法2: 建立主鍵或唯一索引, 利用索引(假設(shè)每頁10條)

  —語句樣式: MySQL中,可用如下方法:?

  SELECT * FROM 表名稱 WHERE id_pk > (pageNum*10) LIMIT M。

  —適應(yīng)場(chǎng)景:?適用于數(shù)據(jù)量多的情況(元組數(shù)上萬)。

  —原因: 索引掃描,速度會(huì)很快。有朋友提出因?yàn)閿?shù)據(jù)查詢出來并不是按照pk_id排序的,所以會(huì)有漏掉數(shù)據(jù)的情況,只能方法3。

  方法3: 基于索引再排序

  —語句樣式: MySQL中,可用如下方法: SELECT * FROM 表名稱?WHERE id_pk > (pageNum*10) ORDER BY id_pk ASC LIMIT M。

  —適應(yīng)場(chǎng)景:?適用于數(shù)據(jù)量多的情況(元組數(shù)上萬). 最好ORDER? BY后的列對(duì)象是主鍵或唯一所以,使得ORDERBY操作能利用索引被消除但結(jié)果集是穩(wěn)定的(穩(wěn)定的含義,參見方法1)。

  —原因: 索引掃描,速度會(huì)很快.?但MySQL的排序操作,只有ASC沒有DESC(DESC是假的,未來會(huì)做真正的DESC,期待)。

  方法4:?基于索引使用prepare(第一個(gè)問號(hào)表示pageNum,第二個(gè)?表示每頁元組數(shù))

  —語句樣式: MySQL中,可用如下方法:?

  PREPARE stmt_name FROM SELECT * FROM 表名稱 WHERE id_pk > (?* ?) ORDER BY id_pk?

  ASC LIMIT M。

  —適應(yīng)場(chǎng)景: 大數(shù)據(jù)量。

  —原因: 索引掃描,速度會(huì)很快. prepare語句又比一般的查詢語句快一點(diǎn)。

  方法5:利用MySQL支持ORDER操作可以利用索引快速定位部分元組,避免全表掃描

  —比如: 讀第1000到1019行元組(pk是主鍵/唯一鍵)。

  —SELECT * FROM your_table WHERE pk>=1000 ORDER BY pk ASC LIMIT 0,20。

  方法6: 利用”子查詢/連接+索引”快速定位元組的位置,然后再讀取元組. 道理同方法5

  —如(id是主鍵/唯一鍵,藍(lán)色字體時(shí)變量):

  利用子查詢示例:

SELECT?*?FROM?your_table?WHERE?id?<p>  	 <strong> 利用連接示例:</strong></p><pre class="brush:sql;">SELECT?*?FROM?your_table?AS?t1  JOIN?(SELECT?id?FROM?your_table?ORDER?BY  id?desc?LIMIT?($page-1)*$pagesize?AS?t2  WHERE  t1.id?<p>  	  <strong>方法7:?存儲(chǔ)過程類(最好融合上述方法5/6)</strong></p><p>  	  ---語句樣式:?不再給出</p><p>  	  ---適應(yīng)場(chǎng)景: 大數(shù)據(jù)量.??<strong>作者推薦的方法</strong></p><p>  	  ---原因: 把操作封裝在服務(wù)器,相對(duì)更快一些。</p><p>  	  <strong>方法8:?反面方法</strong></p><p>  	  ---網(wǎng)上有人寫使用?SQL_CALC_FOUND_ROWS。 沒有道理,勿模仿?。</p><p>  	  基本上,可以推廣到所有數(shù)據(jù)庫,道理是一樣的。但方法5未必能推廣到其他數(shù)據(jù)庫,推廣的前提是,其他數(shù)據(jù)庫支持ORDER?BY操作可以利用索引直接完成排序。</p>

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊10 分享