0

我一直在使用下面的 php 和 sql 来加载英国旅客列车的时刻表信息和实时信息。本质上,您必须找到相关的时间表,然后为每个时间表加载实时信息,这些信息位于与今天的火车相关的不同表格中。

查询花费的时间比真正的想法要长一些,并且使用了大量的 CPU%,这又不是理想的。在 sql 编程方面我很弱,所以任何关于什么是低效的指针都会很棒。

这是一个 android 应用程序,所以我尝试通过 http 进行一次调用。prints(*) 和 > 用于在另一端拆分字符串。

这是代码:

<?

//Connect to the database
 mysql_connect("localhost","XXXX","XXXX")
or die ("No connection could be made to the OpenRail Database");
mysql_select_db("autotrain");
//Set todays date from system and get HTTP parameters for the station,time to find trains         and todays locations table.
$date = date('Y-m-d');
$test = $_GET['station'];
$time = $_GET['time'];
$table = $_GET['table'];

//Find the tiploc associated with the station being searched.
$tiplocQuery = "SELECT tiploc_code FROM allstations WHERE c LIKE '$test';";
$tiplocResult =mysql_query($tiplocQuery);
$tiplocRow = mysql_fetch_assoc($tiplocResult);

$tiploc=$tiplocRow['tiploc_code'];
//Now find the timetabled trains for the station where there exists no departure     information. Goes back two hours to account for any late running.
$timeTableQuery = "SELECT tiplocs.tps_description AS 'C',     locations$table.public_departure, locations$table.id,schedules.stp_indicator
,schedules.train_uid
FROM locations$table, tiplocs, schedules_cache, schedules,activations
WHERE locations$table.id = schedules_cache.id
AND schedules_cache.id = schedules.id
AND schedules.id =activations.id
AND '$date'
BETWEEN schedules.date_from
AND schedules.date_to
AND locations$table.tiploc_code = '$tiploc'
AND locations$table.real_departure LIKE '0'
AND locations$table.public_departure NOT LIKE '0'
AND locations$table.public_departure >='$time'-300
AND locations$table.public_departure <='$time'+300
AND schedules.runs_th LIKE '1'
AND schedules_cache.destination = tiplocs.tiploc
ORDER BY locations$table.public_departure ASC
LIMIT 0,30;";

$timeTableResult=mysql_query($timeTableQuery);


while($timeTablerow = mysql_fetch_assoc($timeTableResult)){
$output[] = $timeTablerow;

}

//Now for each id returned in the timetable, get the locations and departure times so the app may calculate expected arrival times.
foreach ($output as $value) {
$id = $value['id'];
$realTimeQuery ="SELECT     locations$table.id,locations$table.location_order,locations$table.arrival,locations$table.public_arrival,
locations$table.real_arrival,locations$table.pass,locations$table.departure,locations$   table.public_departure,locations$table.real_departure,locations$table.location_cancelled,
tiplocs.tps_description FROM locations$table,tiplocs WHERE id =$id AND     locations$table.tiploc_code=tiplocs.tiploc;";

$realTimeResult =mysql_query($realTimeQuery);
while($row3 = mysql_fetch_assoc($realTimeResult)){
    $output3[] = $row3;
}
print json_encode($output3);
print("*");
unset($output3);
unset($id);
}


print('>');
print json_encode($output);

?>

非常感谢马特

4

3 回答 3

0

我注意到了一些事情。

首先,您在 where 子句中加入表,如下所示

from table1, table2
where table1.something - table2.something

加入 from 子句更快

from table1 join table2 on table1.something - table2.something

接下来,我不是 php 程序员,但看起来您正在循环中运行类似的查询。如果这是真的,请寻找一种只运行一个查询的方法。

编辑从这里开始

这是对 gazarsgo 的回应,我声称 where 子句中的连接更快。他是对的,我错了。这就是我所做的。编程语言是 ColdFusion:

<cfsetting showdebugoutput="no">
<cfscript>
fromtimes = ArrayNew(1);
wheretimes = ArrayNew(1);
</cfscript>

<cfloop from="1" to="1000" index="idx">
<cfquery datasource="burns" name="fromclause" result="fromresult">
select count(distinct hscnumber)
from burns_patient p join burns_case c on p.patientid = c.patientid
</cfquery>
<cfset ArrayAppend(fromtimes, fromresult.executiontime)>

<cfquery datasource="burns" name="whereclause" result="whereresult">
select count(distinct hscnumber)
from burns_patient p, burns_case c 
where p.patientid = c.patientid
</cfquery>
<cfset ArrayAppend(wheretimes, whereresult.executiontime)>
</cfloop>
<cfdump var="#ArrayAvg(fromtimes)#" metainfo="no" label="from">
 <cfdump var="#ArrayAvg(wheretimes)#" metainfo="no" label="where">

我确实跑了5次。结果(以毫秒为单位)如下。

 9.563 9.611
 9.498 9.584 
 9.625 9.548 
 9.831 9.769 
 9.792 9.813 

第一个数字表示加入 from 子句,第二个表示加入 where 子句。第一个数字只有 60% 的时间较低。如果它在 100% 的时间里较低,它会表明加入 from 子句更快,但事实并非如此。

于 2013-02-19T01:36:33.337 回答
0

您设置的最大问题是这个 foreach 循环,因为它是不必要的,并且会导致 n 次往返数据库以执行查询、获取和分析结果。

foreach ($output as $value) {

重写初始查询以包含您以后进行计算所需的所有字段。

像这样的东西会起作用。

SELECT tl.tps_description AS 'C', lc.public_departure, lc.id, s.stp_indicator, s.train_uid,
lc.id, lc.location_order, lc.arrival, lc.public_arrival, lc.real_arrival, lc.pass, lc.departure, lc.real_departure, lc.location_cancelled
FROM locations$table lc INNER JOIN schedules_cache sc ON lc.id = sc.id
  INNER JOIN schedules s ON s.id = sc.id
  INNER JOIN activations a ON s.id = a.id
  INNER JOIN tiplocs tl ON sc.destination = tl.tiploc
WHERE '$date' BETWEEN schedules.date_from AND schedules.date_to
  AND lc.tiploc_code = '$tiploc'
  AND lc.real_departure LIKE '0'
  AND lc.public_departure NOT LIKE '0'
  AND lc.public_departure >='$time'-300
  AND lc.public_departure <='$time'+300
  AND s.runs_th LIKE '1'
ORDER BY lc.public_departure ASC
LIMIT 0,30;

从页面加载中消除 n 次查询执行应该会显着增加响应时间。

于 2013-02-19T03:13:34.777 回答
0

忽略代码中的问题,为了加快查询速度,请使用 EXPLAIN 命令评估需要在查询中添加索引的位置。

猜测一下,您可能希望在任何locations$table.public_departure评估结果上创建一个索引。

http://dev.mysql.com/doc/refman/5.0/en/using-explain.html

于 2013-02-19T03:26:58.317 回答