国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

mysql 百萬條數據分頁優化

2024-07-24 12:39:02
字體:
來源:轉載
供稿:網友

很多程序朋友在寫分頁是特別是mysql有了limit n,m;這樣的寫法,分頁從此簡單了,但方不知道這種分頁幾萬數據沒有問題,但在百萬千萬級時就無法使用了,今天我們來介紹這兩種分頁的優化方法.

PHP寫分頁功能時,只要用的還是MySQL,基本都是兩步走.

1、取得總數,算頁數,SQL語句自然是如下代碼:

SELECT count(*) FROM tablename; 

2、根據指定的頁碼號,取得相應的數據,對應的SQL語句,在網上隨便查,都是一樣的:

SELECT f1,f2 FROM table LIMIT offset,length

實例分頁類,代碼如下:

  1. <?php 
  2. /*********************************************  
  3. 類名:PageSupport 
  4. 功能:分頁顯示MySQL數據庫中的數據  
  5. ***********************************************/  
  6. class PageSupport{  
  7. //屬性 
  8. var $sql//所要顯示數據的SQL查詢語句  
  9. var $page_size//每頁顯示最多行數 
  10.  
  11. var $start_index//所要顯示記錄的首行序號 
  12. var $total_records//記錄總數  
  13. var $current_records//本頁讀取的記錄數  
  14. var $result//讀出的結果 
  15.  
  16. var $total_pages//總頁數  
  17. var $current_page//當前頁數 
  18. var $display_count = 30; //顯示的前幾頁和后幾頁數 
  19.  
  20. var $arr_page_query//數組,包含分頁顯示需要傳遞的參數 
  21.  
  22. var $first
  23. var $prev
  24. var $next
  25. var $last
  26.  
  27. //方法 
  28. /*********************************************  
  29. 構造函數:__construct() 
  30. 輸入參數:  
  31. $ppage_size:每頁顯示最多行數  
  32. ***********************************************/  
  33. function PageSupport($ppage_size
  34. {  
  35. $this->page_size=$ppage_size;  
  36. $this->start_index=0; 
  37.  
  38.  
  39. /*********************************************  
  40. 構造函數:__destruct() 
  41. 輸入參數:  
  42. ***********************************************/  
  43. function __destruct() 
  44.  
  45.  
  46. /*********************************************  
  47. get函數:__get() 
  48. ***********************************************/  
  49. function __get($property_name
  50. {  
  51. if(isset($this->$property_name))  
  52. {  
  53. return($this->$property_name);  
  54. }  
  55. else  
  56. {  
  57. return(NULL);  
  58. }  
  59.  
  60. /*********************************************  
  61. set函數:__set() 
  62. ***********************************************/  
  63. function __set($property_name$value)  
  64. {  
  65. $this->$property_name = $value;  
  66.  
  67. /*********************************************  
  68. 函數名:read_data 
  69. 功能: 根據SQL查詢語句從表中讀取相應的記錄 
  70. 返回值:屬性二維數組result[記錄號][字段名] 
  71. ***********************************************/  
  72. function read_data() 
  73. {  
  74. $psql=$this->sql; 
  75.  
  76. //查詢數據,數據庫鏈接等信息應在類調用的外部實現 
  77. $result=mysql_query($psqlor die(mysql_error());  
  78. $this->total_records=mysql_num_rows($result); 
  79.  
  80. //利用LIMIT關鍵字獲取本頁所要顯示的記錄 
  81. if($this->total_records>0)  
  82. $this->start_index = ($this->current_page-1)*$this->page_size; 
  83. $psql=$psql" LIMIT ".$this->start_index." , ".$this->page_size; 
  84.  
  85. $result=mysql_query($psqlor die(mysql_error());  
  86. $this->current_records=mysql_num_rows($result); 
  87.  
  88. //將查詢結果放在result數組中 
  89. $i=0;  
  90. while($row=mysql_fetch_Array($result)) 
  91. {  
  92. $this->result[$i]=$row;  
  93. $i++;  
  94. }  
  95.  
  96.  
  97. //獲取總頁數、當前頁信息 
  98. $this->total_pages=ceil($this->total_records/$this->page_size);  
  99.  
  100. $this->first=1; 
  101. $this->prev=$this->current_page-1; 
  102. $this->next=$this->current_page+1; 
  103. $this->last=$this->total_pages; 
  104.  
  105. /*********************************************  
  106. 函數名:standard_navigate() 
  107. 功能: 顯示首頁、下頁、上頁、未頁 
  108. ***********************************************/  
  109. function standard_navigate()  
  110. {  
  111. echo "<div align=center>"
  112. echo "<form action=".$_SERVER['PHP_SELF']." method="get">"
  113.  
  114. echo "<font color = red size ='4'>第".$this->current_page."頁/共".$this->total_pages."頁</font>";  
  115. echo " "
  116.  
  117. echo "跳到<input type="text" size=?" name="current_page" value='".$this->current_page."'/>頁"; 
  118. echo "<input type="submit" value="提交"/>"
  119.  
  120.  
  121. //生成導航鏈接 
  122. if ($this->current_page > 1) { 
  123. echo "<A href=".$_SERVER['PHP_SELF']."?current_page=".$this->first.">首頁</A>|";  
  124. echo "<A href=".$_SERVER['PHP_SELF']."?current_page=".$this->prev.">上一頁</A>|";  
  125.  
  126. if$this->current_page < $this->total_pages) { 
  127. echo "<A href=".$_SERVER['PHP_SELF']."?current_page=".$this->next.">下一頁</A>|"
  128. echo "<A href=".$_SERVER['PHP_SELF']."?current_page=".$this->last.">末頁</A>";  
  129.  
  130. echo "</form>";  
  131. echo "</div>"
  132.  
  133.  
  134. /*********************************************  
  135. 函數名:full_navigate() 
  136. 功能: 顯示首頁、下頁、上頁、未頁  
  137. 生成導航鏈接 如1 2 3 ... 10 11 
  138. ***********************************************/  
  139. function full_navigate()  
  140. {  
  141. echo "<div align=center>"
  142. echo "<form action=".$_SERVER['PHP_SELF']." method="get">"
  143.  
  144. echo "<font color = red size ='4'>第".$this->current_page."頁/共".$this->total_pages."頁</font>";  
  145. echo " "
  146.  
  147. echo "跳到<input type="text" size=?" name="current_page" value='".$this->current_page."'/>頁"; 
  148. echo "<input type="submit" value="提交"/>"
  149.  
  150. //生成導航鏈接 如1 2 3 ... 10 11 
  151. $front_start = 1; 
  152. if($this->current_page > $this->display_count){ 
  153. $front_start = $this->current_page - $this->display_count; 
  154. for($i=$front_start;$i<$this->current_page;$i++){ 
  155. echo "<a href=".$_SERVER['PHP_SELF']."?page=".$i.">[".$i ."]</a> ";  
  156.  
  157. echo "[".$this->current_page."]"
  158.  
  159. $displayCount = $this->display_count; 
  160. if($this->total_pages > $displayCount&&($this->current_page+$displayCount)<$this->total_pages){ 
  161. $displayCount = $this->current_page+$displayCount
  162. }else
  163. $displayCount = $this->total_pages; 
  164.  
  165. for($i=$this->current_page+1;$i<=$displayCount;$i++){ 
  166. echo "<a href=".$_SERVER['PHP_SELF']."?current_page=".$i.">[".$i ."]</a> ";  
  167.  
  168. //生成導航鏈接 
  169. if ($this->current_page > 1) { 
  170. echo "<A href=".$_SERVER['PHP_SELF']."?current_page=".$this->first.">首頁</A>|";  
  171. echo "<A href=".$_SERVER['PHP_SELF']."?current_page=".$this->prev.">上一頁</A>|";  
  172.  
  173. if$this->current_page < $this->total_pages) { 
  174. echo "<A href=".$_SERVER['PHP_SELF']."?current_page=".$this->next.">下一頁</A>|"
  175. echo "<A href=".$_SERVER['PHP_SELF']."?current_page=".$this->last.">末頁</A>";   //Vevb.com 
  176.  
  177. echo "</form>";  
  178. echo "</div>"
  179.  
  180.  
  181. }  
  182. ?> 

調用代碼如下:

  1. <?php 
  2.  
  3. include_once("../config_jj/sys_conf.inc");  
  4. include_once("../PageSupportClass.php");//分頁類 
  5. include_once('../Smarty_JsnhClass.php'); 
  6.  
  7. $smarty = new Smarty_Jsnh(); 
  8. include_once("../include/Smarty_changed_dir.php");  
  9. $smarty->assign('title'"Smarty新聞分頁測試"); 
  10.  
  11. <?php 
  12.  
  13. $pageSupport = new PageSupport($PAGE_SIZE); //實例化PageSupport對象 
  14.  
  15. $current_page=$_GET["current_page"];//分頁當前頁數 
  16.  
  17. if (isset($current_page)) { 
  18.  
  19. $pageSupport->__set("current_page",$current_page); 
  20.  
  21. else { 
  22.  
  23. $pageSupport->__set("current_page",1); 
  24.  
  25.  
  26. ?>  
  27. $pageSupport->__set("sql","select * from news ");  
  28. $pageSupport->read_data();//讀數據 
  29.  
  30. if ($pageSupport->current_records > 0) //如果數據不為空,則組裝數據 
  31. for ($i=0; $i<$pageSupport->current_records; $i++) 
  32. $title = $pageSupport->result[$i]["title"]; 
  33. $id = $pageSupport->result[$i]["id"]; 
  34.  
  35. $news_arr[$i] = array('news' => array('id' => $id,'title' => $title)); 
  36.  
  37.  
  38. //關閉數據庫 
  39. mysql_close($db); 
  40.  
  41. $pageinfo_arr = array
  42. 'total_records' => $pageSupport->total_records, 
  43. 'current_page' => $pageSupport->current_page, 
  44. 'total_pages' => $pageSupport->total_pages, 
  45. 'first' => $pageSupport->first, 
  46. 'prev' => $pageSupport->prev, 
  47. 'next' => $pageSupport->next, 
  48. 'last' => $pageSupport->last 
  49. ); 
  50.  
  51. $smarty->assign('results'$news_arr); 
  52. $smarty->assign('pageSupport'$pageinfo_arr); 
  53. $smarty->display('news/list.tpl'); 
  54.  
  55. ?>  

模板list.tpl,代碼如下:

  1. {* I am a Smarty comment, I don't exist in the compiled output *} 
  2. {* 
  3. {$pageSupport.total_records}<br/> 
  4. {$pageSupport.current_page}<br/> 
  5. {$pageSupport.total_pages}<br/> 
  6. {$pageSupport.first}<br/> 
  7. {$pageSupport.prev}<br/> 
  8. {$pageSupport.next}<br/> 
  9. {$pageSupport.last}<br/> 
  10. *} 
  11. <html> 
  12. <head> 
  13. <meta http-equiv="Content-Type" content="text/html; charset=gbk" /> 
  14. <title>{$title}</title> 
  15. </head> 
  16. <body> 
  17.  
  18. {foreach item=o from=$results}  
  19. {$o.news.id} {$o.news.title}  
  20. <br>  
  21. {foreachelse} 
  22. 沒有您要查看的數據! 
  23. {/foreach}  
  24.  
  25. <br/> 
  26.  
  27.  
  28. {if ( $pageSupport.total_records > 0 )} 
  29.  
  30. <form action="" method="get"> 
  31. 共{$pageSupport.total_records}記錄 
  32. 第{$pageSupport.current_page}頁/共{$pageSupport.total_pages}頁 
  33. {if ( $pageSupport.current_page > 1 )} 
  34. <A href=?current_page={$pageSupport.first}>首頁</A> 
  35. <A href=?current_page={$pageSupport.prev}>上一頁</A> 
  36. {/if} 
  37.  
  38. {if ( $pageSupport.current_page < $pageSupport.total_pages )} 
  39. <A href=?current_page={$pageSupport.next}>下一頁</A> 
  40. <A href=?current_page={$pageSupport.last}>末頁</A> 
  41. {/if} 
  42.  
  43. 跳到<input type="text" size="4" name="current_page" value="{$pageSupport.current_page}"/>頁 
  44. <input type="submit" value="GO"/> 
  45. </form> 
  46.  
  47. {/if} 
  48. </body> 
  49. </html> 

語法,不解釋了,數據量小的時候,這么寫,沒事,如果數據量大呢?不是一般大,上百萬呢.

試著運行一下:SELECT id FROM users LIMIT 1000000,10

在我的電腦上,第一次運行,顯示如下:

10 rows in set (9.38 sec)

之后再運行,顯示如下:

10 rows in set (0.38 sec)

這不奇怪,MySQL對已經運行的SQL語句有緩沖,可以很快把之前的數據拿出來,無論如何,第一次的9秒多,我實在不能接受.

換個寫法,代碼如下:

SELECT id FROM users WHERE id>1000000 LIMIT 10;

顯示:10 rows in set (0.00 sec)

事實上,用phpMyAdmin去看,“顯示行 0 - 9 (10 總計,查詢花費 0.0011 秒)”,之后再運行,基本都在0.0003秒左右.

百萬級優化,對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引.

2.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,代碼如下:

select id from t where num is null

可以在num上設置默認值0,確保表中num列沒有null值,然后這樣查詢:

select id from t where num=0

3.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。

4.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,代碼如下:

select id from t where num=10 or num=20

可以這樣查詢,代碼如下:

  1. select id from t where num=10 
  2.  
  3. union all 
  4.  
  5.      select id from t where num=20 

5.in 和 not in 也要慎用,否則會導致全表掃描,代碼如下:

select id from t where num in(1,2,3) 

對于連續的數值,能用 between 就不要用 in 了,代碼如下:

select id from t where num between 1 and 3 

6.下面的查詢也將導致全表掃描,代碼如下:

select id from t where name like '%abc%' 

分類函數,代碼如下:

  1. $db=dblink(); 
  2. $db->pagesize=20; 
  3. $sql=”select id from collect where vtype=$vtype”; 
  4. $db->execute($sql); 
  5. $strpage=$db->strpage(); //將分頁字符串保存在臨時變量,方便輸出 
  6. while($rs=$db->fetch_array()){ 
  7.    $strid.=$rs['id'].’,'; 
  8. $strid=substr($strid,0,strlen($strid)-1); //構造出id字符串 
  9. $db->pagesize=0; //很關鍵,在不注銷類的情況下,將分頁清空,這樣只需要用一次數據庫連接,不需要再開; 
  10. $db->execute(“select id,title,url,sTime,gTime,vtype,tag from collect where id in ($strid)”); 
  11. <?php while($rs=$db->fetch_array()): ?> 
  12. <tr> 
  13.     <td>&nbsp;<?php echo $rs['id'];?></td> 
  14.     <td>&nbsp;<?php echo $rs['url'];?></td> 
  15.     <td>&nbsp;<?php echo $rs['sTime'];?></td> 
  16.     <td>&nbsp;<?php echo $rs['gTime'];?></td> 
  17.     <td>&nbsp;<?php echo $rs['vtype'];?></td> 
  18.     <td>&nbsp;<a href=”?act=show&id=<?php echo $rs['id'];?>” target=”_blank”><?php echo $rs['title'];?></a></td> 
  19.     <td>&nbsp;<?php echo $rs['tag'];?></td> 
  20. </tr> 
  21. <?php endwhile; ?> 
  22. </table> 
  23. <?php 
  24. echo $strpage
  25. ?>

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 普安县| 寻乌县| 灌云县| 定边县| 航空| 屏东市| 巫溪县| 武邑县| 云安县| 贵溪市| 两当县| 纳雍县| 甘谷县| 娄底市| 武夷山市| 永州市| 河津市| 新绛县| 濮阳市| 威宁| 尤溪县| 北京市| 奉贤区| 微山县| 白玉县| 宜兰县| 冀州市| 明水县| 台安县| 疏勒县| 神木县| 吉隆县| 清新县| 贺兰县| 丹江口市| 边坝县| 堆龙德庆县| 宁陕县| 大荔县| 蛟河市| 潞城市|