mysql 分页有数据没了_mysql分页丢数据的分析

1 有问题的代码

如下面的代码,system_user表有400万行数据,这时候需要把这张表里面的所有的userid取出来。这时候只能分页取,一次取2万。

//系统用户表(400万行的数据)

$systemUserTable = new systemUserTable();

// 每次取20000

$pageSize = 20000;

for($curPage = 1;; $curPage++) {

$sql = "select userid from system_user order by userid asc limit " . (($curPage - 1) * $pageSize) . "," . $pageSize;

//取数据

$rows = $systemUserTable->fetchAll($sql);

// 没有数据了,结束

if (empty($rows)) {

break;

}

// 遍历数据

foreach ( $rows as $key => $val ) {

$userid = $val['userid'];

echo $userid."\r\n";

}

}

2 问题分析 1)假如system_user只有10行数据(u1,u2,u3,u4,u5,u6,u7,u8,u9,u10)。

2) 这时候每次取5行。分2两次取。

3)正常情况第一页取(u1,u2,u3,u4,u5),正常情况第二页取(u6,u7,u8,u9,u10)。

4)如果在第一页去完,第二页取之前的时间间隙里面。u2,u3被删除了。

5)那么第二页取的时候。数据变成了(u1,u4,u5,u6,u7,u8,u9,u10)。

6)那么取出来第二页的数据就变成了(u8,u9,u10)。

7)u6,u7被丢失了。

3 解决方案 每次取的时候where带着最大偏移量。如下面的代码。

$systemUserTable = new systemUserTable();

// 每次取20000

$pageSize = 20000;

// 每页最大编号

$pageMaxId = 0;

while ( 1 ) {

$sql = "select userid from system_user where userid > ${pageMaxId} order by userid asc limit " . $pageSize;

//取数据

$rows = $fyHouse->fetchAll($sql);

// 没有数据,结束

if (empty($rows)) {

break;

}

// 遍历数据

foreach ( $rows as $key => $val ) {

$userid = $val['userid'];

// 记录当前最大分页编号

if ($userid > $pageMaxId) {

$pageMaxId = $userid;

}

echo $userid."\r\n";

}

}

过程分析: 1)system_user只有10行数据(u1,u2,u3,u4,u5,u6,u7,u8,u9,u10)。 2) 第一次取,最大偏移量0,limit 5;则取出(u1,u2,u3,u4,u5)。记录最大的偏移量u5的值。 4)如果在第一页去完,第二页取之前的时间间隙里面。u2,u3被删除了。 5)那么第二页取的时候。数据变成了(u1,u4,u5,u6,u7,u8,u9,u10)。 3)第二次取,最大偏移量u5,limit 5;则取出(u6,u7,u8,u9,u10)。记录最大的偏移量u10的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值