2014-12-03 59 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