我正在嘗試優化在應用程序中被稱爲真正的「瓶頸」功能。需要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)
目前的「瓶頸」功能做到這一點:
- 檢查2指定的選項限制了對方。
- 如果不是,它檢查選項1是否爲選項包,如果是,則檢索所有選項並檢查是否有任何選項受限。
- 如果不是,則檢查選項2是否爲選項包,如果是這樣,請檢索它的所有選項,並檢查是否有選項1限制。
- 如果不是,則返回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的資源/時間。
相對限制多久改變一次?也許緩存包限制可能是一個選擇? – Mchl 2010-08-12 18:56:20
無法判斷,用戶可以在應用程序運行時隨時更改它。 – Activist 2010-08-12 18:59:08