日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > php >内容正文

php

php超大树形分页,PHP+MySql千万级数据limit分页优化方案

發(fā)布時(shí)間:2025/3/12 php 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php超大树形分页,PHP+MySql千万级数据limit分页优化方案 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

PHP+MySql千萬(wàn)級(jí)數(shù)據(jù)limit分頁(yè)優(yōu)化方案

1年前

閱讀 2750

評(píng)論 0

喜歡 0

### 原因

徒弟突然有個(gè)需求,就是他發(fā)現(xiàn)limit分頁(yè),頁(yè)數(shù)越大之后,mysql的消耗越大,查詢時(shí)間越長(zhǎng),當(dāng)突破百萬(wàn)級(jí)數(shù)據(jù)之后,一個(gè)簡(jiǎn)單的翻頁(yè)都需要5-6秒,極其不方便。

### 測(cè)試數(shù)據(jù)庫(kù)結(jié)構(gòu)

```

CREATE TABLE IF NOT EXISTS `video_info` (

`id` int(10) unsigned NOT NULL COMMENT '自增ID',

`channel_id` varchar(30) DEFAULT NULL COMMENT '頻道ID',

) ENGINE=InnoDB AUTO_INCREMENT=4565068 DEFAULT CHARSET=utf8mb4;

ALTER TABLE `video_info`

ADD PRIMARY KEY (`id`),

ADD KEY `channel_id` (`channel_id`);

ALTER TABLE `video_info`

MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',AUTO_INCREMENT=1;

```

上面數(shù)據(jù)庫(kù)隨機(jī)生成700W數(shù)據(jù),進(jìn)行效率測(cè)試。

### ThinkPHP5.1的分頁(yè)代碼:

```php

namespace app\index\controller;

use think\Controller;

class Index extends Controller

{

public function index() {

$page = !empty($_GET['page']) ? $_GET['page'] : 1;

$limit = !empty($_GET['limit']) ? $_GET['limit'] : 10;

$where = [];

$param = '?';

if (!empty($_GET['keys'])) {

$where[] = ['channel_id', 'like', '%'.$_GET['keys'].'%'];

$param .= 'keys='.$_GET['keys'];

}

$total = \think\Db::name('video_info')->where($where)->count();

// 取最后一條記錄做翻頁(yè)條件

$sql = \think\Db::name('video_info')->where($where)->limit((($page-1)*$limit), 1)->field('id')->buildSql();

$list = \think\Db::name('video_info')->where($where)->where('id >= '.$sql.'')->limit($limit)->field('id, channel_id')->select();

$this->assign('page', $page);

$this->assign('limit', $limit);

$this->assign('param', $param);

$this->assign('total', $total);

$this->assign('list', $list);

// 渲染模板輸出

return $this->fetch();

}

}

```

### 原生PHP的分頁(yè)代碼:

```php

//程序運(yùn)行時(shí)間

$starttime = explode(' ',microtime());

# 設(shè)置html頁(yè)面為UTF-8編碼

header("Content-type:text/html;charset=utf-8");

# 使用MySqli連接數(shù)據(jù)庫(kù)

$DB = mysqli_connect('127.0.0.1', 'localhost_db', 'localhost_db', 'localhost_db', 3306);

# 設(shè)置數(shù)據(jù)庫(kù)為UTF-8編碼

mysqli_query($DB, 'set names utf8');

$page = !empty($_GET['page']) ? $_GET['page'] : 1;

$limit = !empty($_GET['limit']) ? $_GET['limit'] : 10;

$where = ' 1=1';

$param = '?';

if (!empty($_GET['keys'])) {

$where .= ' AND channel_id like "%'.$_GET['keys'].'%"';

$param .= 'keys='.$_GET['keys'];

}

$sql = 'SELECT COUNT(*) AS count FROM video_info where'.$where;

# 使用mysqli_query()執(zhí)行SQL語(yǔ)句

$res = mysqli_query($DB, $sql);

# 判斷是否執(zhí)行成功

if ($res == false) {

echo '查詢失敗'; exit;

}

$array= mysqli_fetch_array($res);

$total = $array['count'];

$sql = ' SELECT `id`,`channel_id` FROM `video_info` WHERE '.$where.' AND ( id >= ( SELECT `id` FROM `video_info` WHERE '.$where.' LIMIT '.(($page-1)*$limit).', 1 ) ) LIMIT '.$limit;

$res = mysqli_query($DB, $sql);

# 判斷是否執(zhí)行成功

if ($res == false) {

echo '查詢失敗'; exit;

}

$list= mysqli_fetch_all($res, MYSQLI_ASSOC);

//程序運(yùn)行時(shí)間

$endtime = explode(' ',microtime());

$thistime = $endtime[0]+$endtime[1]-($starttime[0]+$starttime[1]);

$thistime = round($thistime,7);

$title = "本網(wǎng)頁(yè)執(zhí)行耗時(shí):".$thistime." 秒";

?>

test page

搜索

ID渠道ID
<?php echo $v['id'];?><?php echo $v['channel_id'];?>

function getParameter(name) {

var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");

var r = window.location.search.substr(1).match(reg);

if (r!=null) return unescape(r[2]); return null;

}

//init

$(function(){

var totalPage = <?php echo $total/$limit;?>;

var totalRecords = <?php echo $total;?>;

var pageNo = getParameter('page');

if(!pageNo){

pageNo = 1;

}

//生成分頁(yè)

//有些參數(shù)是可選的,比如lang,若不傳有默認(rèn)值

kkpager.generPageHtml({

pno : pageNo,

//總頁(yè)碼

total : totalPage,

//總數(shù)據(jù)條數(shù)

totalRecords : totalRecords,

//鏈接前部

hrefFormer : '/2/index.php',

//鏈接尾部

hrefLatter : '',

getLink : function(n){

return this.hrefFormer + this.hrefLatter +'<?php echo $param;?>'+"&page="+n;

}

/*

,lang: {

firstPageText: '首頁(yè)',

firstPageTipText: '首頁(yè)',

lastPageText: '尾頁(yè)',

lastPageTipText: '尾頁(yè)',

prePageText: '上一頁(yè)',

prePageTipText: '上一頁(yè)',

nextPageText: '下一頁(yè)',

nextPageTipText: '下一頁(yè)',

totalPageBeforeText: '共',

totalPageAfterText: '頁(yè)',

currPageBeforeText: '當(dāng)前第',

currPageAfterText: '頁(yè)',

totalInfoSplitStr: '/',

totalRecordsBeforeText: '共',

totalRecordsAfterText: '條數(shù)據(jù)',

gopageBeforeText: '?轉(zhuǎn)到',

gopageButtonOkText: '確定',

gopageAfterText: '頁(yè)',

buttonTipBeforeText: '第',

buttonTipAfterText: '頁(yè)'

}*/

//,

//mode : 'click',//默認(rèn)值是link,可選link或者click

//click : function(n){

//this.selectPage(n);

// return false;

//}

});

});

```

### 最終效果

在沒(méi)優(yōu)化之前,正常的limit翻頁(yè)到4.5W頁(yè),最后一頁(yè)時(shí),需要耗時(shí)22秒左右,優(yōu)化之后則只需要花費(fèi)1.5秒,提高了17倍左右的查詢速度。

### 原理和缺點(diǎn):

原理很簡(jiǎn)單,就是使用子查詢獲得max(id),然后進(jìn)行當(dāng)前分頁(yè)。

缺點(diǎn)也很明顯,那就是分頁(yè)的關(guān)鍵參數(shù),id值只能為自增主鍵,否則這個(gè)方案用不了。

? 著作權(quán)歸作者所有

總結(jié)

以上是生活随笔為你收集整理的php超大树形分页,PHP+MySql千万级数据limit分页优化方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。