2013-05-29 21 views
0

我從數據庫中獲取數據。每個結果看起來像這樣在PHP中唯一地結合數千個數組的最快方法

ASDF-1234-JKL-F1-STUFF 

有50,000個結果。每一個被爆炸

$exploded = explode('-',$dash_delimited_datum); 

// $exploded = array('ASDF','1234','JKL','F1','STUFF'); 

我嘗試這樣做:

$data = array(); 

while($row = mysql_fetch_array($result)){ 
    $i++; 
    if($i > 99999) { 
     break; 
    } 
    $data = array_merge($data,explode('-',$row[0])); 
} 

但是我打了5分鐘,它的服務器超時。

而這並沒有在所有的工作:沒想到

while($row = mysql_fetch_array($result)){ 
    $i++; 
    if($i > 99999) { 
     break; 
    } 
    $data_parts = explode('-',$row[0]); 
    foreach($data_parts as $value) { 
     $data = array_push(($data,$value); 
    } 
} 

,這個工作,以 「只有」 9秒,但我不知道如果我可以使它更快:

while($row = mysql_fetch_array($result)){ 
    $i++; 
    if($i > 99999) { 
     break; 
    } 
    $data = array_unique(array_merge($data,explode('-',$row[0]))); 
} 

編輯:我想出了一個解決方案,我認爲將是最好的,在800毫秒 請注意,我用「封閉」(匿名函數)刪除數字鍵,我認爲這是一個速度拖動。但實際上,刪除它會導致腳本在30秒後超時。

$data=array(); 
while($row = mysql_fetch_array($result)){ 
    $i++; 
    if($i > 99999) { 
     break; 
    } 
    $data_parts = array_flip(array_filter(explode('-',$row[0]), 
    function($value) { 
     if(is_numeric($value)) { 
       return false; 
     } else return true; 
    })); 

    $data = array_merge($data,$data_parts); 
} 
$data = array_keys($data); 
sort($data); 

結論:

每個快速回答使用技巧涉及數組鍵,而不是值。我的最佳答案和下面兩個非常快速的答案之間的差異似乎是while loopforeach的使用,它們將值直接分配給主要的$data陣列。 PHP 功能調用據說很貴,這個例子似乎證明他們真的是。這兩個最佳答案在300毫秒以內給了我結果。當我篩選出數字值時,我的最佳答案只能工作得很快,否則會遇到30秒的服務器超時。

所以,我想,如果你正在處理大量的數據,只要你能使用結構不是功能

請注意(是的,我知道他們已棄用)mysql函數 一個答案建議我使用mysql_fetch_assoc而不是mysql_fetch_array。實際上,mysql_fetch_row應該是「最快的」,但是這種改變使用該數據集的頁面加載速度(約48,000個結果)完全沒有區別。我也嘗試使用mysql_result。 PHP文檔說,檢索多行時速度較慢,速度較慢。

加載時間爲6.27秒,而類似結構的最佳答案爲約0.27秒(270毫秒)。

$i=0; 
while($data_parts = explode('-',mysql_result($result,$i,0))){ 
    $i++; 
    if($i > 99999) { 
     break; 
    } 
    foreach($data_parts as $value) { 
     $data[$value] = 1; 
    } 
} 
$data = array_keys($data); 
+0

嘗試使用'mysql_fetch_assoc',而不是'mysql_fetch_array'。 mysql_fetch_array返回數字和關聯索引(有效地加倍數組的大小)。另外,儘量在'while'循環中儘量使用一些小函數。例如,如果迭代50,000個元素,並且在每次迭代中都有3次函數調用,那麼函數被調用的次數是150,000次。 –

+0

你可以通過將'array_unique'移動到循環之外來加速它。 – h2ooooooo

回答

1

這個怎麼樣(我刪除您的櫃檯,但你可以在如果需要添加回):

$data = array(); 
$i = 0; 

while($row = mysql_fetch_array($result)) 
{ 
    $data_parts = explode('-',$row[0]); 

    foreach($data_parts as $value) 
    { 
     if (!isset($data[$value])) 
      $data[$value] = $i++; 
    } 
} 

$data = array_flip($data); 

我真的不能基準我的計算機上,因此如果慢於你實現,讓我知道!

+0

我剛剛想出了一個解決方案,該解決方案在890ms內交付給我的瀏覽器。我非常驚訝地發現你的解決方案更快,大約300毫秒!奇怪的是,我們需要付出多少努力來有效地創建PHP流程數組。 –

+0

用你的方法,DOM在255到265毫秒內被加載。有趣的是,當我添加'$ j + = count($ data_parts)'來查看處理了多少個數組元素時,它增加了大約15ms。當'&& is_numeric($ value)'檢查你的if語句時(因爲我實際上只對字符串值感興趣),它也增加了大約15ms。我想這說明了函數調用的成本。 –

+0

我也嘗試刪除你的'if(!isset($ data [$ value]))'語句。我沒有看到它的重點,因爲鍵無論如何都必須是唯一的。但刪除它幾乎沒有什麼區別,甚至可能會增加5-10ms。我還會在最後使用'$ data = array_keys($ data)',而不是'$ data = array_flip($ data)',但結果時間不受它的影響。 –

2

爲了加速,而不是使用昂貴的函數來處理陣列,使用關聯數組(散列),以確保唯一值的過程中,應具有整體更快

$i = 0; 
$hash = array(); 

while($row = mysql_fetch_array($result)) { 
    $i++; 
    if($i > 99999) { 
     break; 
    } 
    foreach (explode('-', $row[0]) as $s) { 
     $hash[ $s ] = 1; 
    } 
} 

這樣,所有字符串是唯一存儲在關聯數組(稱爲散列)。

所得陣列是$hash鍵($data

$data = array_keys($hash); 
print_r($data); 
+1

所有php數組都是關聯的。 – symcbean

+0

我的意思是...以聯合的方式使用它,就像在Perl中一樣。除了使用索引數組(無論如何這都是關聯的,但這不是重點),我們希望使用數組鍵的好處,這些鍵是唯一的,並且可以快速訪問。 –

+0

您的答案導致DOM負載在270毫秒內。很好。這是解析48,000個結果,其中爆炸時處理240,991個數組元素。這是在我的臺式機上的虛擬機上運行的! –

0

使用mysql_fetch_assoc代替mysql_fetch_array的嘗試。 mysql_fetch_array返回數字和關聯索引(有效地加倍數組的大小)。另外,儘量在while循環中儘可能使用一些小函數。例如,如果迭代50,000個元素,並且在每次迭代中都有3次函數調用,那麼函數被調用的次數是150,000次。

另外,爲什麼甚至沒有經過結果循環之前剝離重複?

SELECT someField 
FROM someTable 
GROUP BY someField 
HAVING COUNT(someField)>0 

一旦運行,運行循環

$data = array(); 

while($row = mysql_fetch_assoc($result)){ 
    $i++; 
    if($i > 99999) { 
     break; 
    } 

    $data[] = explode('-',$row[0]); 
} 
+0

您提出一個很好的問題,關於mysql_fetch_array比mysql_fetch_assoc慢。但實際上,因爲我得到一個單獨的列,我不妨使用mysql_fetch_row,它返回「快速」數字鍵。有趣的是,使用其中的任何一個都不會對我的劇本的速度產生絲毫的影響。我會在我的問題中添加更多關於此的註釋。另外,我相信你的循環有問題,因爲每個'explode'都會添加一個數組作爲一個元素,從而創建一個多變暗的數組。此外,您的查詢建議不起作用。數據是獨一無二的,但我沒有在' - '上爆炸。 –

相關問題