2013-08-16 96 views
-1

我必須優化硬腳本。當前運行時間〜5小時。如何優化?

腳本通過md5哈希查找表文件中的重複項使用表文件夾。

DB:MySQL,server:local。
計算機:AsRock Z77 pro4,英特爾酷睿i7 3770,12GB內存。

代碼:

// find file-duplicates by md5-hash 
$current_folder_id = 1; 
$select_ids_files = array(); 

$folders = $this->db->query(" 
    SELECT `folder_id` 
    FROM `sc_folders` 
")->result(); 

if (!$folders) 
    exit('folders not found'); 

$current_files_data = $this->get_files_by_folder_id($current_folder_id); 
if (!$current_files_data) { 
    exit('!current_files_data'); 
} 

foreach ($folders as $folder) { 
    $files = (object)array(); 
    $files = $this->get_files_by_folder_id($folder->folder_id); 

    if (!$files) 
     continue; 

    if (count($files) > count($current_files_data)) { 
     $gl_arr = &$files; 
     $nogl_arr = &$current_files_data; 
    } else { 
     $gl_arr = &$current_files_data; 
     $nogl_arr = &$files; 
    } 

    foreach ($gl_arr as $key => $value) { 
     foreach ($nogl_arr as $k => &$v) { 
      if ($value->file_hash == $v->file_hash && $value->file_id != $v->file_id) { // an important place for optimize 
       $select_ids_files[] = $v->file_id; 
      } 
     } 
    } 
} 

print_r($select_ids_files);exit; // id duplicates records 

表文件夾:folder_id,FOLDER_NAME。 (約45條記錄)
表文件:file_id,file_hash,file_folder_id,file_name。 (約1,400,000條記錄)

+2

哪一部分需要所有時間?嘗試對其進行分析或至少回顯各個時間點的時間,以查看需要優化的部分 – Anigel

+0

@Anigel'if($ value-> file_hash == $ v-> file_hash && $ value-> file_id!= $ v- > file_id)'= 99%的時間。 – iproger

+4

它看起來像所有的文件哈希存儲在數據庫中爲什麼不直接選擇重複哈希直接在SQL查詢類似'select * from files group by hash having count(hash)> 1',而不是每個140萬個循環其中循環1。400萬東西 – Anigel

回答

0

不使用foreach {foreach {}}。使用foreach {in_array()}。

-50%時間。

1

首先,它可能是非常有幫助狀態,你實際上試圖實現。

從我可以從源代碼閱讀:

  • 你有一個數據表,包含鏈接的文件和它們的哈希值。
  • 想要(定期)檢查文件是否被插入,更改或刪除?

提出的第一個問題:如何是插入,刪除或編輯的文件?用戶是直接訪問文件夾還是通過任何類型的應用程序發生?

如果它是通過應用程序發生的,則應更新該點,並標記數據庫中任何過時的條目。像UPDATE files SET 'requires_approval'=1 WHERE filename LIKE '{$current_changed_file}'

如果這事情是不是這樣的(用戶正在編輯,刪除,在文件系統級插入文件),你可以通過以下操作優化你的檢查:

  • 保存時間戳(即您的數據庫中的ANY文件的最新修改日期)。
  • 檢查更改時,只考慮修改日期較晚的文件。

喜歡的東西

foreach ($files as $file){ 
    if (filemtime($file) > $my_stored_modification_time){ 
     //refresh the data-row 
    } 
} 

(識別刪除,你可以遍歷所有文件entrys(數據庫),並使用is_file - 你不需要關心文件的哈希值缺失,因爲你甚至不能生成它們)

+0

謝謝你的答案(誰給我-1?)。 我的文件夾與文件。 http://s018.radikal.ru/i504/1308/09/d1a90da9da88.png – iproger

+0

算法: 1.我得到一個文件(大約30,000周)。 2.每週我創建一個文件夾(2013 -..- ..) 3.通過我的程序掃描文件(創建xml-list並使用php插入到mysql中)。 3.5。比較文件以刪除重複項。 4.我可以爲舊文件夾中的其他人提供文件(2012 -..- ..)。 評論3.5: 我不能刪除舊文件夾中的文件(我希望你明白爲什麼)。 – iproger

+0

仍然沒有得到它。正如@ dognose所說,檢查重複的時間是在添加新的和可能重複的文件時。這在添加時會很昂貴,但您也可以將其添加到CheckForDuplicates表並在預定的後臺任務中處理該表。 –