0

以下の php と sql を使用して、英国の旅客列車のスケジュール情報とリアルタイム情報をロードしています。基本的に、関連するスケジュールを見つけて、今日の列車に関連する別のテーブルにある各スケジュールのリアルタイム情報をロードする必要があります。

クエリは実際のアイデアよりも少し時間がかかり、多くの CPU% を使用していますが、これも理想的ではありません。私はSQLプログラミングに関してはかなり弱いので、何が非効率的であるかについてのポインタは素晴らしいでしょう.

これはAndroidアプリ用なので、httpを介した1回の呼び出しですべてを試しました。プリント (*) と > は、もう一方の端で文字列を分割するためのものです。

コードは次のとおりです。

<?

//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

セットアップの最大の問題は、この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 に答える
0

気になった点をいくつか。

まず、このように where 句でテーブルを結合しています

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

from 句での結合は高速です

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

次に、私は php プログラマーではありませんが、ループ内で同様のクエリを実行しているようです。その場合は、クエリを 1 つだけ実行する方法を探してください。

ここから編集開始

これは、where 句での結合が高速であるという主張によってバックアップした gazarsgo への対応です。彼は正しい、私は間違っていた。これが私がしたことです。プログラミング言語は 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 句での結合を表し、2 番目の数字は where 句での結合を表します。最初の数値は、60% の確率でのみ低くなります。100% の割合で低い場合は、from 句での結合の方が高速であることが示されますが、そうではありません。

于 2013-02-19T01:36:33.337 に答える