2010-08-12 49 views
1

我正在嘗試優化在應用程序中被稱爲真正的「瓶頸」功能。需要PHP/SQL(MySQL)函數優化幫助

在相關應用程序中,可以選擇選項。但有些選項可能會受到其他選項的限制。例如,選擇選項「A」時,限制選項「B」的選擇。

這些限制鏈接保存有該結構的表格:

option_restrictions 
    option_code_1 varchar(20) 
    option_code_2 varchar(20) 

還有些選項是選件包。例如,選項「水果」由選項「Apple」,「Orange」,「Kiwi」組成。

那些在表中這樣定義:

option_packages 
    option_code  varchar(20) 
    option_included varchar(20) 

目前的「瓶頸」功能做到這一點:

  1. 檢查2指定的選項限制了對方。
  2. 如果不是,它檢查選項1是否爲選項包,如果是,則檢索所有選項並檢查是否有任何選項受限。
  3. 如果不是,則檢查選項2是否爲選項包,如果是這樣,請檢索它的所有選項,並檢查是否有選項1限制。
  4. 如果不是,則返回false(不限制)。

這裏是我想要優化的實際代碼:

//Returns true if options restricts each other, false otherwise 
function restriction($option_1, $option_2) { 
    global $conn; 

    //Pass 1 check is each option restrict themselves 
    $sql_restriction = "select * from option_restrictions where (option_code_1 = '".$option_1."' or option_code_1 = '".$option_2."') and (option_code_2 = '".$option_1."' or option_code_2 = '".$option_2."')"; 
    $res_restriction = mysql_query($sql_restriction, $conn); 
    if (mysql_num_rows($res_restriction)>0) { 
     log_action('End restriction(' . $option_1 . ', ' . $option_2 . ')'); 
     return true; 
    } else { 
     //Pass 2 check if option 1 is a package and if so test it's options against option 2 
     $sql_option_1_composante = "select * from option_packages where option_code = '".$option_1."'"; 
     $res_option_1_composante = mysql_query($sql_option_1_composante, $conn); 
     if (mysql_num_rows($res_option_1_composante)>0) { 
      while ($option_1_composante = mysql_fetch_array($res_option_1_composante)) { 
       if (restriction($option_1_composante["option_included"], $option_2)) { 
        return true; 
       } 
      } 
     } 
     //Pass 3 check if option 2 is a package and if so test it's options against option 1 
     $sql_option_2_composante = "select * from option_packages where option_code = '".$option_2."'"; 
     $res_option_2_composante = mysql_query($sql_option_2_composante, $conn); 
     if (mysql_num_rows($res_option_2_composante)>0) { 
      while ($option_2_composante = mysql_fetch_array($res_option_2_composante)) { 
       if (restriction($option_2_composante["option_included"], $option_1)) { 
        return true; 
       } 
      } 
     } 
    } 

    return false; 
} 

遞歸調用/環路查殺系統ATM ......對於單一頁面加載這一功能可以被稱爲超過15000個導致頁面加載時間爲30秒/ 4分鐘的次數!

我想盡可能地優化。我試圖合併通過2和3在一起,並刪除遞歸調用...任何想法歡迎!

僅供參考,我知道這可能不是最好的設計,但是這個功能是leviathan系統的一部分,我無法控制,也沒有改變ATM的資源/時間。

+0

相對限制多久改變一次?也許緩存包限制可能是一個選擇? – Mchl 2010-08-12 18:56:20

+0

無法判斷,用戶可以在應用程序運行時隨時更改它。 – Activist 2010-08-12 18:59:08

回答

1

我不能確定沒有更多的細節,但對我來說這聽起來像一個數據庫設計問題。

如果它確實是一個數據庫設計問題,

  • 你可能不會得到很遠 優化應用程序代碼
  • 但改變結構可能急劇下降的加載時間,甚至幾個數量級

這是我用概念驗證測試成功攻擊的那種問題(遺留系統,不允許更改它)。我在自己的電腦上安裝了一臺服務器。 (現在Oracle XE,SQL Server Express和PostgreSQL都是免費的。)然後,我會建立表格和視圖,完成所有這些繁瑣的工作。

就你而言,如果你不是數據庫設計師,找到一個願意參與到臭鼬工程項目中的人。

祝你好運。我的意思是。