Php 无法完成对大型数据集的排序
这是一个后续行动,因为我现在有时间继续这个项目 这个问题我有三张表:Php 无法完成对大型数据集的排序,php,mysql,sorting,memory,query-optimization,Php,Mysql,Sorting,Memory,Query Optimization,这是一个后续行动,因为我现在有时间继续这个项目 这个问题我有三张表: 海报数据中的840721张海报 海报类别中的58506个海报类别 17629007(1700多万)海报/海报类别组合 基于Yahoo!的高效分页演示!,我试图在poster_prodcat中添加一个类别排名编号,这样我们就可以按排名分页,而不是使用限制和偏移。尽管将我的php mysql连接超时设置为3600(我知道这很疯狂),并将php超时设置为0,但排序似乎从未完成。也许几十到十万左右,但从来没有完整的17000000套
海报数据中的840721张海报
海报类别中的58506个海报类别
17629007(1700多万)海报/海报类别组合 基于Yahoo!的高效分页演示!,我试图在poster_prodcat中添加一个类别排名编号,这样我们就可以按排名分页,而不是使用限制和偏移。尽管将我的php mysql连接超时设置为3600(我知道这很疯狂),并将php超时设置为0,但排序似乎从未完成。也许几十到十万左右,但从来没有完整的17000000套 以下是脚本:
$sql1="select distinct apcatnum from poster_prodcat";
$result1 = mysql_query($sql1);
while ($cats = mysql_fetch_array ($result1)) {
$sql2 = "SELECT poster_data.apnumber,poster_data.aptitle
FROM poster_prodcat,poster_data
WHERE poster_prodcat.apcatnum ='$cats[apcatnum]'
AND poster_data.apnumber = poster_prodcat.apnumber
ORDER BY aptitle ASC";
$result2 = mysql_query($sql2);
$ordernum=1;
while ($order = mysql_fetch_array ($result2)) {
$sql3 = "UPDATE poster_prodcat SET catorder='$ordernum'
WHERE apnumber='$order[apnumber]' AND apcatnum='$cats[apcatnum]'";
$result3 = mysql_query($sql3);
$ordernum++;
}
}
这是在一个2 gig服务器上,该服务器也承载该站点。超时时间很长,服务器没有崩溃,所以我不知道是什么阻止了它的完成。我可以在这个服务器上做这件事吗,或者因为这是一个每月一次的操作,我应该创建一些大内存EC2实例,在那里进行排序并下载经过处理的表吗
谢谢
以下是poster_数据的结构(删除了一些与选择无关的字段):
海报(prodcat):
CREATE TABLE `poster_prodcat` (
`apcatnum` mediumint( 8 ) NOT NULL DEFAULT '0',
`apnumber` mediumint( 8 ) NOT NULL DEFAULT '0',
`catorder` mediumint( 7 ) NOT NULL DEFAULT '0',
PRIMARY KEY ( `apcatnum` , `apnumber` ) ,
KEY `apcatnum` ( `apcatnum` ) ,
KEY `apnumber` ( `apnumber` ) ,
KEY `catorder` ( `catorder` )
) ENGINE = InnoDB /*!50100 PARTITION BY HASH (apcatnum) PARTITIONS 10 */;
这是否意味着您要执行1700万个单独的事务?如果你能维持每秒1000个事务,单是这一部分就需要大约5个小时,对吗
维基百科(很容易获得,但不是我认为权威的)这样说。
在完全符合酸性条件下运行时 模式下,InnoDB必须刷新磁盘 不过,每笔交易至少一次 它将为插入合并刷新 来自多个连接。典型的 旋转硬盘驱动器或阵列 将限制在200左右 每秒更新事务向我们展示您的查询和表ddl创建脚本的计划。@克里斯·巴克勒:需要更新才能按类别将排名号添加到海报数据中。因此,是的,每个记录都需要更新。同样,在下载新数据时,大约每月只做一次。@Ian-刚刚用200万条记录尝试了类似的方法,只需15秒。我想你可能陷入了无限循环或其他什么。当一个计数器在250k,1M,5M时,你能让它输出吗?只是为了确保它不会被挂断……如果你在之前删除订单,会对时间产生影响吗?@Chris Buckler:我想知道,由于2Gig服务器同时运行web服务器和邮件,是否因为缺少inno密钥缓冲区而需要这么长时间。这三个inno表(我仅有的三个inno表)的数据大小为687.8M,缓冲池只有128.0M。很明显,这是一个糟糕的表现。启动一个大型EC2实例一个小时,看看是否需要几秒钟。是的,当我运行EC2服务器只是为了处理这个问题时,需要几个小时。想不出更好的方法来处理这个问题。@Ian:我查阅了“Yahoo的高效分页演示文稿”,找到了以下url:。我看不出有什么像你想做的。我看到的是正确的演示吗?在第14页,他们讨论了使用另一种类型的顺序值而不是“限制M,N”来分页结果。在我的例子中,我正在为数千个类别创建顺序值。因此,您正在创建一个新列来保存排序顺序,而不是像幻灯片中那样使用id号,对吗?他们的方法可能工作得很好,但通过使用现有的id号,他们不必更新1700万行。
CREATE TABLE `poster_prodcat` (
`apcatnum` mediumint( 8 ) NOT NULL DEFAULT '0',
`apnumber` mediumint( 8 ) NOT NULL DEFAULT '0',
`catorder` mediumint( 7 ) NOT NULL DEFAULT '0',
PRIMARY KEY ( `apcatnum` , `apnumber` ) ,
KEY `apcatnum` ( `apcatnum` ) ,
KEY `apnumber` ( `apnumber` ) ,
KEY `catorder` ( `catorder` )
) ENGINE = InnoDB /*!50100 PARTITION BY HASH (apcatnum) PARTITIONS 10 */;
while ($order = mysql_fetch_array ($result2)) {
$sql3 = "UPDATE poster_prodcat SET catorder='$ordernum'
WHERE apnumber='$order[apnumber]' AND apcatnum='$cats[apcatnum]'";
$result3 = mysql_query($sql3);
$ordernum++;
}
}