大型数据集的排序无法完成

时间:2011-04-13 20:30:09

标签: php mysql sorting memory query-optimization

这是debugging a mysql insert fail in php的后续内容,因为我现在有时间继续这个项目。

我在这个问题上有三个表:
poster_data中的840,721张海报
poster_categories中58,506个海报类别
poster_prodcat中有17,629,007(1700万+)张海报/类别组合

基于Yahoo!的Efficient Pagination演示,我正在尝试向poster_prodcat添加类别排名,以便我们可以按排名进行分页,而不是使用限制和偏移。尽管我的php mysql连接超时启动到3600(疯狂,我知道)和转换php超时,订单似乎永远不会完成。也许几十到十万左右,但从未完整的17,000,000套。

这是脚本:

$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_data的结构(删除了一些不参与选择的字段):

CREATE  TABLE  `poster_data` (
`apnumber` mediumint( 8  )  NOT  NULL DEFAULT  '0',
`aptitle` varchar( 255  )  NOT  NULL DEFAULT  '',
`aptype` varchar( 100 ) NOT NULL DEFAULT '',
[snip]
UNIQUE  KEY  `posterid` (  `apnumber`  ) ,
KEY  `aptitle` (  `aptitle`  ) ,
KEY  `aptype` (  `aptype`  ) ,
KEY  `title_type` (  `aptitle` ,  `aptype`  )  ) ENGINE  = InnoDB;

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 */;

1 个答案:

答案 0 :(得分:0)

  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++;
    }
  }

这是否意味着您正在执行1700万个独立交易?如果你每秒可以维持一千笔交易,那么这部分只需要5个小时,对吗?

维基百科(随时可用,但不是我认为具有权威性的)关于innodb transactions的说法。

  

完全符合ACID标准的操作   模式,InnoDB必须刷新到磁盘   但是,每笔交易至少一次   它将结合冲洗用于插入   来自多个连接。对于典型的   旋转硬盘或阵列,这个   将限制约200   每秒更新一次交易。