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

PHP+MySql千万级数据limit分页优化方案

6cd5e4fd49658da7be73f2e8e3760c00.png

1年前

阅读 2750

评论 0

喜欢 0

### 原因

徒弟突然有个需求,就是他发现limit分页,页数越大之后,mysql的消耗越大,查询时间越长,当突破百万级数据之后,一个简单的翻页都需要5-6秒,极其不方便。

### 测试数据库结构

```

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;

```

上面数据库随机生成700W数据,进行效率测试。

### ThinkPHP5.1的分页代码:

```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();

// 取最后一条记录做翻页条件

$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的分页代码:

```php

//程序运行时间

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

# 设置html页面为UTF-8编码

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

# 使用MySqli连接数据库

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

# 设置数据库为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()执行SQL语句

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

# 判断是否执行成功

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);

# 判断是否执行成功

if ($res == false) {

echo '查询失败'; exit;

}

$list= mysqli_fetch_all($res, MYSQLI_ASSOC);

//程序运行时间

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

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

$thistime = round($thistime,7);

$title = "本网页执行耗时:".$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;

}

//生成分页

//有些参数是可选的,比如lang,若不传有默认值

kkpager.generPageHtml({

pno : pageNo,

//总页码

total : totalPage,

//总数据条数

totalRecords : totalRecords,

//链接前部

hrefFormer : '/2/index.php',

//链接尾部

hrefLatter : '',

getLink : function(n){

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

}

/*

,lang: {

firstPageText: '首页',

firstPageTipText: '首页',

lastPageText: '尾页',

lastPageTipText: '尾页',

prePageText: '上一页',

prePageTipText: '上一页',

nextPageText: '下一页',

nextPageTipText: '下一页',

totalPageBeforeText: '共',

totalPageAfterText: '页',

currPageBeforeText: '当前第',

currPageAfterText: '页',

totalInfoSplitStr: '/',

totalRecordsBeforeText: '共',

totalRecordsAfterText: '条数据',

gopageBeforeText: ' 转到',

gopageButtonOkText: '确定',

gopageAfterText: '页',

buttonTipBeforeText: '第',

buttonTipAfterText: '页'

}*/

//,

//mode : 'click',//默认值是link,可选link或者click

//click : function(n){

//this.selectPage(n);

// return false;

//}

});

});

```

### 最终效果

在没优化之前,正常的limit翻页到4.5W页,最后一页时,需要耗时22秒左右,优化之后则只需要花费1.5秒,提高了17倍左右的查询速度。

### 原理和缺点:

原理很简单,就是使用子查询获得max(id),然后进行当前分页。

缺点也很明显,那就是分页的关键参数,id值只能为自增主键,否则这个方案用不了。

© 著作权归作者所有

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/560066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux自启动配置文件,Linux中如何设置服务自启动?

有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务&#xff0c;主要用三种方式进行这一操作&#xff1a;ln -s 在/etc/rc.d/rc*.d目录中建立/etc/init.d/服务的软链接(*代表0&#xff5e;6七个运行级别之一)chkonfig 命令行运行级别设置nts…

linux系统下升级node,linux下安装指定版本的nodejs(升级到指定版本)

原因最近需要全栈开发但是服务器是linux系统&#xff0c;服务本身通过yum安装软件包&#xff0c;不过yum安装的nodejs版本太低。所以需要自己安装。方案下载编译好的文件解压后直接运行即可&#xff0c;不过我们需要全局运行node命令。只需要把目录设置为全局即可(建立软链接 l…

Linux bash卸载软件,Ubuntu卸载软件的4种方法

前言本文重点介绍Ubuntu卸载软件的4种方法。他们分别是图形化界面的synaptic、自动解决依赖关系的apt-get&#xff0c;处理依赖关系更强大的aptitude&#xff0c;还有安装本地deb包的dpkg。方法一: Ubuntu使用synaptic图形化界面管理软件oucanrongzcwyou:~$ sudo apt-get insta…

linux系统atom安装教程,Ubuntu/Linux Mint上安装Atom文本编辑器

Atom是一款由Github开发的开源文本编辑器&#xff0c;虽然目前该软件依然在Beta阶段&#xff0c;但我们依然可以在你的Ubuntu/Linux Mint上使用它。据Atom官方博客介绍&#xff0c;与Atom类似的编辑器Sublime和TextMate都深受开发者欢迎&#xff0c;但在扩展性上都有所限制&…

labview 远程连接linux,SSH交互式通信总结:expect、plink、putty、sshpass、ALAB SSH

关于在linux脚本中远程执行命令的问题&#xff0c;笔者在以前文章中可以使用expect工具来完成交互式通信。在windows平台下可以使用plink或者putty工具。免密也可以设置SSH秘钥&#xff0c;参考文章-Linux怎么远程执行指令呢-SSH秘钥。但是在linux下需要一一对应设置&#xff0…

tcping在linux用法,tcping的安装和使用

Tcping 网上比较少资料是关于linux对tcp端口ping测试的方法&#xff0c;我这里简单介绍2种方法&#xff1a; 1.yum安装&#xff0c;编译安装方法 1-1.wget http://linuxco.de/tcping/tcping-1.3.5.tar.gz ###下载tcping1-2 tar zxvf tcping-1.3.5.tar.gz ####解压缩tcping-1.3.…

linux子系统安装gromacs,科学网—Windows下GROMACS程序的编译 - 李继存的博文

2015-12-07 22:12:05总的来说, Windows下的GROMACS程序用于模拟意义不大, 对于长时间的模拟, 我都是放在Linux服务器上进行的. 但将Windows下的GROMACS程序作为一个辅助工具来使用还是有意义的. 因为大多数时候, 我都是在Windows下准备输入文件的, 然后测试一下准备好的输入文件…

林锐 高质量c语言编程下载,新年献礼:Go语言深度入门手册

(文末的阅读原文&#xff0c;效果最佳&#xff01;)作者&#xff1a;李佶澳 微信&#xff1a;lijiaocnGo 语言深度入门手册&#xff0c;帮你更好的理解 Go 语言&#xff0c;写出更高效、更规范、更不易出错的代码。Go 在 2012 年发布 1.0 版本&#xff0c;距今已经 8 年了。和历…

永洪报表工具_2020年最值得推荐的五大BI工具

现在很多公司和业务部门都十分注重数据分析&#xff0c;并为企业信息化建设做准备。以前收集、处理、分析数据可能是IT部门和数据库员的专属&#xff0c;现在很多业务部门都急切的开始用数据分析的思维分析业务问题。在过去&#xff0c;大多数数据人员的工作模式都是自己使用ex…

容量耦合系数模型_期刊在线 | 基于ALE流固耦合方法的刷式密封泄漏特性理论与实验研究...

01引言刷式密封是一种广泛应用于航空发动机等透平机械的优良接触式动密封[]。近年来&#xff0c;随着透平机械逐渐向高参数方向发展&#xff0c;由刷式密封引起的泄漏损失越来越大&#xff0c;直接影响透平机械的工作效率。因此开展刷式密封的泄漏流动特性研究具有重要理论和实…

设备管理器android感叹号,设备管理器其他设备感叹号

设备管理器其他设备感叹号客观地讲&#xff0c;常规的设备管理器问题与设备管理器在哪&#xff0c;设备管理其怎么打开以及设备管理其其他设备感叹号是什么问题等。本文重点介绍设备设备管理器其他设备感叹号相关问题&#xff0c;希望能够为对此有需求的朋友提供参考或帮助。设…

android studio 集成 第三方sdk,Android FrameWork集成第三方SDK的jar包和so庫

本文講解的如何在Android FrameWork如何集成XXXsdk的jar包和so庫首先在framework/opt/建立XXSDK的文件夾講jar包和so庫拷貝進去1:framework/opt/xxsdk/然后直接看Android.mk就行# Copyright (C) 2009 The Android Open Source Project## Licensed under the Apache License, Ve…

unity要学ecs吗_ECS的泛泛之谈

这篇文章将带着你从设计出发重新发现ECS。注意:此篇为泛泛之谈&#xff0c;不涉及具体实现。从Abstract说起从”是”到”能”再到”有”对对象的抽象是整理代码的要点&#xff0c;继承是一种比较古老并常见的抽象&#xff0c;其描述了一个对象"是"什么&#xff0c;其…

条令考试小程序辅助器_计算机一级考试干货!

计算机一级考试干货一年两度的计算机等级考试就要在2019年3月30-31日期间开始啦&#xff01;为了更好的让同学们了解考试的大体内容&#xff0c;我们已整理如下内容&#xff0c;可以供大家参考。同时&#xff0c;希望大家认真备考&#xff0c;争取都一次性过哦&#xff01;考试…

燃气灶电气线路图及原理_一位造价大神的电气工程造价知识整理笔记_深圳电气造价预算培训要多少钱...

电气设备安装工程是建设工程中的一种常见的、重要的设备安装工程。电气设备安装工程计价涉及到许多电气工程专业知识。一、电气设备安装工程的组成一般的电气设备安装工程是以接受电能&#xff0c;经变换、分配电能&#xff0c;到使用电能或从接受电能经过分配到用电设备所形成…

荣耀es升级鸿蒙,华为手机明年全部升级鸿蒙系统 所有自研设备换OS

近日&#xff0c;华为举行 HarmonyOS 2.0 手机开发者 Beta 活动&#xff0c;现场正式发布了 HarmonyOS 2.0 手机开发者 Beta 版本。华为消费者业务软件部副总裁杨海松在接受媒体采访表示&#xff0c;到今天为止&#xff0c;参与鸿蒙开发项目的开发者数量超过 10 万&#xff0c;…

腐蚀国内稳定服务器_工控机箱和服务器机箱区别在哪里

服务器机箱必须能够装进机柜&#xff0c;一个标准机柜的宽度是19英寸482.6mm&#xff0c;所以机箱的宽度是几乎固定的&#xff0c;一般是17英寸左右&#xff0c;两侧再安装把手和轨道。机箱高度也有规定&#xff0c;用U(Unit)做单位&#xff0c;1U是44.5mm&#xff0c;机箱高度…

limit实现原理 mysql_解读数据库:深入分析MySQL中事务以及MVCC的实现原理

什么是事务事务&#xff08;Transaction)是由一系列对数据库中的数据进行访问与更新的操作所组成的一个程序执行单元。在同一个事务中所进行的操作&#xff0c;要么都成功&#xff0c;要么就什么都不做。理想中的事务必须满足四大特性&#xff0c;这就是大名鼎鼎的ACID。事务的…

c# 审批流引擎_小熊OA:流程引擎才能真正起到管理价值!

首先说说什么是流程管理。流程作为企业运作的基础&#xff0c;不同部门、不同客户和供应商都需要流程来进行协同运作&#xff0c;以流程带动信息、物资和资金在企业内部无障碍地流转。流程管理是一种以业务流程为中心&#xff0c;以提高组织业务绩效为目的的系统化方法。它是一…

在计算机桌面上添加小工具日历,实用桌面小工具时钟日历在win7中的添加方法...

我们在win7系统的使用中&#xff0c;小伙伴们都是知道的系统可以直接选择安装不同的小工具在电脑中使用&#xff0c;比如电脑中的时钟日历等都是可以直接安装在桌面来使用的牡丹石有小伙伴对于时钟日历不知道是在哪里添加到桌面的&#xff0c;对于这个疑问今天小编就来跟大家分…