2017-09-25 94 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