2013-02-19 3 views
0

Я использовал приведенные ниже php и sql для загрузки информации о расписании и информации в режиме реального времени для пассажирских поездов в Великобритании. По сути, вам нужно найти соответствующие расписания, а затем загрузить информацию о реальном времени для каждого расписания, которое находится в другой таблице, относящейся к сегодняшним поездам.Более эффективный способ выполнения SQL-запросов

Запрос занимает немного больше времени, чем на самом деле идея и использование большого количества процессоров%, которые снова не идеальны. Я довольно слабый, когда дело доходит до программирования sql, поэтому любые указатели относительно того, что является неэффективным, были бы замечательными.

Это приложение для Android и поэтому я попробовал всех с одним вызовом по http. Отпечатки (*) и> предназначены для разделения строки на другом конце.

Вот код:

<? 

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

?> 

Большое спасибо Matt

+5

[** Пожалуйста, не используйте '' * mysql_ функции в новом коде **] (http://bit.ly/phpmsql). Они больше не поддерживаются [и официально устарели] (https://wiki.php.net/rfc/mysql_deprecation). См. [** красное поле **] (http://j.mp/Te9zIL)? Узнайте о [* подготовленных операторах *] (http://j.mp/T9hLWi) и используйте [PDO] (http://php.net/pdo) или [MySQLi] (http://php.net/ mysqli) - [эта статья] (http://j.mp/QEx8IB) поможет вам решить, какой из них. Если вы выберете PDO, [здесь хороший учебник] (http://j.mp/PoWehJ). –

+0

О, хорошо, спасибо за ссылку. Я изменю способ, которым я это сделаю. Тем не менее проблема с sql thats и причиной замедления любого руководства там будет встречено со многими благодарностями. –

+0

@Matt: сначала определите, как вы собираетесь изменить свою базу кода (использовать PDO или MySQLi), реализовать это изменение, а затем вернуться к нам с конкретными вопросами, связанными с этим кодом. Это действительно не место для спекулятивных общих советов или рекомендаций. –

ответ

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 запросов при загрузке страницы должно резко увеличить время отклика.

+1

Я хочу повысить полезность ответа, но хочу, чтобы уменьшить вероятность блокировки SQL-инъекций. – gazarsgo

+0

отредактируйте ответ, чтобы устранить уязвимость внедрения sql (я не разработчик php) – Tahbaza

0

Несколько вещей, которые я заметил.

Во-первых, вы присоединяетесь таблицы в пункте где, как этот

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

Вхождение в ЕКОМ быстрее

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

Далее, я не программист PHP, но похоже, что вы выполняете похожие запросы внутри цикла. Если это так, найдите способ запустить только один запрос.

Edit начинается здесь

Это в ответ на 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, второе соединение в условии where. Первое число меньше всего в 60% случаев. Если бы он был ниже на 100% в процентах случаев, это показало бы, что соединение в предложении from происходит быстрее, но это не так.

+0

, пожалуйста, предоставьте доказательства таких утверждений, как «присоединение к предложению from быстрее». – gazarsgo

0

Игнорируя проблемы с кодом, чтобы ускорить ваш запрос, используйте команду EXPLAIN, чтобы оценить, где вам нужно добавить индексы в ваш запрос.

При угадывании вы, вероятно, захотите создать индекс, на который оценивается locations$table.public_departure.

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

Смежные вопросы