我有一个在线商店,每天有大约15,000种产品可以更新.目前我每天上传新列表,但它会带来一些问题(比如停机时间是一个很大的问题),我想提出一个替代方案.我创建了一个脚本来移动"昨天"产品列表并下载今天的产品列表.然后我逐行逐行比较两个文件,看看需要删除,修改和创建的内容.这将允许我以最少的工作量执行更新,没有停机时间,因为一切都将通过CRON作业在幕后发生,它应该如何完成.
我遇到的问题是这个过程需要四个多小时才会发生,我不确定我所做的是最有效的方式.我的第一个想法是用C++编写一些东西,但我不确定与PHP相比会有多快.
我的问题是:
•这是最有效的方法吗?
•PHP是最好的语言吗?
这是我编写的用于处理下载和比较的脚本:
public function __construct($url, $user, $pass) { $this->logger = new KLogger("/opt/lampp/htdocs/lea/logs/master.log" , KLogger::INFO); /* increase execution time and server memory limit */ ini_set('max_execution_time', 14400); ini_set('memory_limit', '-1'); /* set veriables */ $this->ftp = ftp_connect($url); $this->login = ftp_login($this->ftp, $user, $pass); $this->old = file('/opt/lampp/htdocs/lea/products/new/temp/rsr_inventory.txt'); $this->new = file('/opt/lampp/htdocs/lea/products/new/rsr_inventory.txt'); $this->list = array(); $this->start_time = date('Hi'); $this->counter = 0; } public function download($to, $from) { // move current file to new location to get new file ready $this->logger->LogInfo('move yesterday\'s products list'); rename('/opt/lampp/htdocs/lea/products/new/temp/rsr_inventory.txt', '/opt/lampp/htdocs/lea/products/new/rsr_inventory.txt'); // get list from rsr $this->logger->LogInfo('get new list from rsr'); if(ftp_get($this->ftp, $to, $from, FTP_BINARY)) { return true; } return false; } public function update() { // initialize process $this->logger->LogInfo('update process initialized'); for($i = 0; $i < count($this->new); $i++) { $new[$i] = explode(';', $this->new[$i]); $response = $this->_match($new[$i]); if($response[0]) { if(trim($response[2]) != trim($new[$i][5]) || trim($response[3]) != trim($new[$i][8])) { $this->list[$this->counter][0] = $response[1]; $this->list[$this->counter][1] = 'update'; $this->list[$this->counter][2] = trim($response[2]); $this->list[$this->counter][3] = trim($response[3]); $this->counter++; } } else { $this->list[$this->counter][0] = $response[1]; $this->list[$this->counter][1] = 'create'; $this->list[$this->counter][2] = trim($response[2]); $this->list[$this->counter][3] = trim($response[3]); $this->counter++; } } if(count($this->list) > 0) { //csv $this->logger->LogInfo('create update.csv'); $updates = fopen('/opt/lampp/htdocs/lea/products/new/updates.csv', 'w'); foreach($this->list as $fields) { fputcsv($updates, $fields); } fclose($updates); } $this->logger->LogInfo('product update process complete'); $this->__mail(); } private function _match($item) { for($j = 0; $j < count($this->old); $j++) { $old[$j] = explode(';', $this->old[$j]); if($item[0] === $old[$j][0]) { return array(true, $item[0], $old[$j][5], $old[$j][8]); } } return array(false, NULL, NULL, NULL); }
这是我每天都得到的products.txt文件的一个例子(我只展示了10种产品,但是大约有15,000种产品(有很多东西缺失;价格,数量等等......但是我缩短了一切因为显示那些并不重要):
511-10010-019-L-XL;844802282208;5.11 RECON ANKLE SOCK BLK L/XL; 511-10010-036-L-XL;844802282246;5.11 RECON ANKLE SOCK SHADOW L/XL; 511-10010-132-LXL;844802334662;5.11 RECON ANKLE SOCK TIMBER L/XL; 511-10010-200-L-XL;844802282222;5.11 RECON ANKLE SOCK FATIGUE L/XL; 511-10011-019-L-XL;844802276382;5.11 COLD WEATHER OTC SOCK BLK L/XL; 511-10012-019-L-XL;844802276429;5.11 COLD WEATHER CREW SOCK BLK L/XL; 511-30012-019-M;844802269650;5.11 WOMENS HOLSTER SHIRT BLK M; 511-40011-010-L;844802016148;5.11 HOLSTER SHIRT L WHITE; 511-40011-010-M;844802016131;5.11 HOLSTER SHIRT M WHITE; 511-40011-010-XL;844802016155;5.11 HOLSTER SHIRT XL WHITE; 511-40011-010-XXL;844802016162;5.11 HOLSTER SHIRT 2XL WHITE;
Mats Peterss.. 5
我认为您的问题是您正在进行15000 x 15000比较(因此对数据进行了2.25亿次操作).
如果您改为创建一个映射(换句话说,PHP中的数组),并使用一些唯一标识符作为旧的和新的索引.这是30k操作,然后迭代一个列表检查另一个是否包含相同的东西.那是另外15K的操作.总共45,000次操作,而不是225M操作.
我不是说建立数据库的建议是一个坏主意,但是过多的时间显然是由于算法+数据结构选择不当造成的.
我认为您的问题是您正在进行15000 x 15000比较(因此对数据进行了2.25亿次操作).
如果您改为创建一个映射(换句话说,PHP中的数组),并使用一些唯一标识符作为旧的和新的索引.这是30k操作,然后迭代一个列表检查另一个是否包含相同的东西.那是另外15K的操作.总共45,000次操作,而不是225M操作.
我不是说建立数据库的建议是一个坏主意,但是过多的时间显然是由于算法+数据结构选择不当造成的.