2014-12-03 60 views
0

我被賦予了製作Web應用程序的任務,以取代由於用戶數量不斷增加而不斷鎖定的Excel預訂表單。 (約一百可能的資產)的預訂數據庫看起來是這樣的:在php視圖中結合MYSQL查詢

+--------------------+---------------+------+-----+---------+-------+ 
| Field    | Type   | Null | Key | Default | Extra | 
+--------------------+---------------+------+-----+---------+-------+ 
| ID     | int(11)  | NO | PRI | 0  |  | 
| bookedDate   | date   | YES |  | NULL |  | 
| bookedBy   | varchar(256) | YES |  | NULL |  | 
| startDate   | date   | YES |  | NULL |  | 
| endDate   | date   | YES |  | NULL |  | 
| Equipment1   | varchar(512) | YES |  | NULL |  | 
| Equipment2   | varchar(512) | YES |  | NULL |  | 
| ...    |    |  |  |   |  | 
| Equipment15  | varchar(512) | YES |  | NULL |  | 
+--------------------+---------------+------+-----+---------+-------+ 

這樣用戶就可以預定了多達15個資產在預定期限1D-1Y的。

在我的PHP頁面顯示視圖(只預訂資產所示)看起來是這樣的:

 <<< << < Prev week Bookings for week 49 - 2014 Next week > >> >>> 
     Monday  Tuesday Wednesday Thursday Friday  Saturday Sunday 
    01/12/2014 02/12/2014 03/12/2014 04/12/2014 05/12/2014 06/12/2014 07/12/2014 
--------------------------------------------------------------------------------- 
Eq1 | fred      tom  tom  tom     harry 
Eq4 | tom  tom          frank 
Eq66 |              tom   tom 
... 
Eq832|       harry 

這所有的作品,但頁面很慢。 20-30秒,以產生具有約50個資產 挑選顯示哪些資產(約需3秒)的代碼的頁面是:

function read_Equipment($sDate,$eDate){ 
    $query = mysql_query("SELECT Equipment1 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment2 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment3 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment4 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment5 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment6 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment7 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment8 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment9 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment10 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment11 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment12 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment13 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment14 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' union 
     SELECT Equipment15 FROM oldDB WHERE startDate<'$sDate' AND endDate>'$eDate' 
     order by Equipment1")or die(); 
    while($ad= mysql_fetch_array($query)){ 
     if($ad['Equipment1'] != "") 
     { 
      $rdata[$ad['Equipment1']] = $ad['Equipment1']; 
     } 
    } 
    return($rdata); 
} 

並獲得每一天代碼(需要大約120毫秒,以及圍繞在20S總)看起來像這樣

function read_booking($equipment,$sDate,$eDate){ 
    $query = mysql_query("SELECT * FROM oldDB WHERE startDate<'$sDate' AND endDate>='$eDate' AND (
     Equipment1 = '$equipment' OR 
     Equipment2 = '$equipment' OR 
     Equipment3 = '$equipment' OR 
     Equipment4 = '$equipment' OR 
     Equipment5 = '$equipment' OR 
     Equipment6 = '$equipment' OR 
     Equipment7 = '$equipment' OR 
     Equipment8 = '$equipment' OR 
     Equipment9 = '$equipment' OR 
     Equipment10 = '$equipment' OR 
     Equipment11 = '$equipment' OR 
     Equipment12 = '$equipment' OR 
     Equipment13 = '$equipment' OR 
     Equipment14 = '$equipment' OR 
     Equipment15 = '$equipment' 
     )")or die(); 
    $rdata = ""; 
    while($ad = mysql_fetch_array($query)){ 
     if($ad != "") 
     { 
      $rdata += $ad['ID']." - "; 
     } 
    } 
    return($rdata); 
} 

的代碼,把他們放在一起看起來像這樣

//$time_i = time at start of the week 
$tepp = read_Equipment($sDate,$eDate); 
foreach($tepp as $time){ 
    echo '<tr><th class="booking_time_th">' . $time . '</th>'; 
    $i = 0; 
    while($i < 7){ 
     $i++; 
     $msc=microtime(true); 
     $strtmp = read_booking($time,date('Y-m-d', $time_i+($i)*24*3600),date('Y-m-d', $time_i+($i-1)*24*3600)); 
     echo '<td>'.(microtime(true)-$msc).'s<div class="booking_time_div"> 
     <div class="booking_time_cell_div" id="div:' . $strtmp . '" onclick="void(0)">' . $strtmp. '</div></div></td>'; 
    } 
    echo '</tr>'; 
} 
echo '</table>'; 

的microtimes就在那裏跟蹤進度和不影響第t總長度非常多。

所以我的問題是我怎樣才能更好地結合sql查詢,以便沒有數百個小查詢(數百個在0.1ms總共20-30s)? 我應該重新整理數據庫嗎?

+0

你當然可以更好地重新排列這個,但我沒有時間做一個例子(我敢肯定其他人會很快給出一個例子!)但是,我會開始確保你有索引您可能會搜索到的列,看起來像所有這些列。這將加快東西LOT – rjdown 2014-12-03 02:11:13

回答

0

我會親自給每個資產一個「ID」,並將他們的表格標記爲資產。然後我會創建一個設備表,其中的第一列將是'asset_id'。 'asset_id'將是資產表中'id'列的外鍵。這將創建從特定資產到設備表中任意數量行的鏈接 - 有效消除15件設備的當前限制。這是一個EAV表結構。

再說,我會用雄辯從Laravel 4或CodeIgniter的ActiveRecord的:https://ellislab.com/codeigniter/user-guide/database/active_record.html

考慮建立利用框架的系統。

編輯:索引也將加快您的搜索。我會索引startDate,endDate和搜索中使用的任何字段(當前所有設備字段)。但是,請注意,儘管這會加快SELECT查詢速度,但會稍微減慢對此表的INSERT查詢速度。另外,如果您切換到上述的EAV結構,您可以索引更少的列以實現相同,更快的結果。

+0

感謝您的回覆。我不認爲我的數據庫佈局足夠清晰。資產是可以預訂的設備。我喜歡你爲擁有所有資產的資產單獨列表的想法,但這張表會比我想象的要大5-10倍。會給它一個去看看結果。也在研究框架。 – ash 2014-12-03 03:39:32

+0

速度問題是您的重複查詢。即使這個新表有更多的條目,但允許MYSQL進行搜索實際上會大大加快速度。MYSQL旨在搜索包含數百萬條記錄的表。否則,請稍微索引幫助。 – 2014-12-03 03:41:53