2017-09-25 96 views
0

我的PHP脚本是这样的,它的工作原理,它模拟像它是从SQL查询中加入,但它不是最优化,一切都在RAM中,有人可以帮助我如何优化和根据第一个CSV文件的“连接”的左侧,只从其他CSV中加载必要的行和列中的RAM?另外,如果它能够模拟WHERE子句,那么它应该查看更少的数据,是真的吗?PHP脚本

<pre> 
    <?php 
    ini_set('memory_limit', '1024M'); 

    $city = array_map('str_getcsv', file('a.csv')); 
    $table = array_map('str_getcsv', file('c.csv')); 

    function left_join_array($left, $right, $left_join_on, $right_join_on){ 
     $final= array(); 

     foreach($left AS $k => $v){ 
      $final[$k] = $v; 
      foreach($right AS $kk => $vv){ 
       if($v[$left_join_on] == $vv[$right_join_on]){ 
        foreach($vv AS $key => $val) 
         $final[$k][$key] = $val; 
       } 
      } 
     } 
     return $final; 
    } 
    $new_table = left_join_array($table, $city, 4, 0); 
    print_r($new_table); 

我a.csv文件看起来像这样:

70106,Belgrade 
70114,New York 
70122,London 
70220,Moscow 

我c.csv文件看起来像这样:

id | id_continent  | id_country | zip_code | id_city 
1  Europe    England  WC2N 5DU 70122 
2  North America  USA  10004  70114 
3  Europe    Belgrade  11000  70106 
4  Europe    Moscow  101000  70220 
+0

这个文件有多大?你内存不足了吗?如果不是,为什么这很重要? RAM很便宜。 – ADyson

+0

@ADyson它包含的行2畅想,性能我想只加载必要的数据,并且使脚本更快,只与需要 – MPetrovic

+0

你不能加载到内存“只有你所需要的数据”的数据工作因为您必须先将数据加载到RAM中(从磁盘),然后才能读取它并检查是否需要它。第二十二条军规。当然,你可以尝试单独读取文件的每一行,然后在不需要的时候丢弃它,但是你必须测试这是否比在一次操作中从磁盘中提取整个文件更有效,给定的行数。 – ADyson

回答

0

永远不要加载您的内存大文件。你认为一个好主意总是会变成一个糟糕的主意。你可以做的第一个优化是使用一个发电机为$表如:

function getTable($file) { 
    $h = fopen($file, "r"); 
    while (($line = fgets($h)) !== false) { 
     yield str_getcsv($line); 
    } 
    fclose($h); 
} 

其次你left_join_array功能是一个问题,它的速度是O(n^3),速度很慢,并尽可能内存去你分配吨也是如此,但在我们谈论如何优化数据之前,我需要更多关于您想要处理数据的信息。

编辑:这基于您的评论是我的编辑答案。

MySQL将总是比任何你能在几分钟内写速度更快,尤其是如果你没有关于如何RDBMS工作的任何知识。您可以尽可能多地模拟它,但MySQL应该至少快一个数量级; MySQL的连接算法是O((n*m) log(n*m)),你的算法指数级地慢(字面上)。

如果这只是为了学习代码或者其他目的的测试,你能做的最好的是,你应该只使用发电机功能上述两个$城市$表的情况。

+0

我想比较MySQL的SQL查询的执行时间和相同的表PHP脚本执行时间(CSV文件),所以我模拟SQL查询来获取最近的结果与此算法,而是要最贴近,它需要进行优化,也许还可以使用where子句来减少启动一些数据? – MPetrovic

+0

评论中没有足够的空间来回答这个问题,所以请检查我编辑的答案。 – thelmuxkriovar

+0

好的,我感谢你的回答,我不认为我能写出比MySQL更快的数据库引擎,那不是目的,目的就是测试。但我的问题是如何优化我现有的代码,如何仅通过模拟算法中的where子句来加载所需的部分或如何剪切数据。甚至有可能做这样的事情? – MPetrovic