У меня есть определеный flow который я пытаюсь оптимизировать. Моя главная проблема это медлительность программы. Пользователи подключаются через token, remote connection и потому даже оптимизированный код бежит медленно. Пытаюсь понять, есть ли возможность построить сам процесс подругому, так как подход у меня был "в лоб", это мой первый проэкт в php. Проект - в БД находятся все данные нужные для работы. Пользователи получают каждый раз окно с данными каждой строчки в БД. Заходить могут сразу несколько пользователей, при начале работы над строчкой, она "закрывается" на пользователя. После просмотра данных, пользователь дает ответ и нажимает на submit получая следущею строку (если таковая существует) Как процесс работает: Initialize.php - queries the DB based on some algo. and prepares one row (or none if there is no more) View.php - shows the row content to the user and gives him a form to fill. Update.php - When the user clicks on submit from the view, this php updates the DB and calls initialize to have a new row prepared. Проблема в том что между нажатием на submit и до получения следущего VIEW могут пройти 2-8 секунд. Оптимизация queries снизила предедущее время 5-10 секунд на 2-8 но мне кажется и это много. Можно ли подойти к этому процессу иначе? Возможно ли готовить следущею строку в то время как пользователь смотрит на View?
зависит конечно от самого запроса и объема данных. но... индексы вы создавали? если нет то скорее всего правильное их создание ускорит запросы на порядок
Создавала (на то что выбираю ) Сами query занимают от 1-1.5 секунд. А submit берет от 2-8. Вот и мучаюсь...
Я бы посоветовал погонять запросы сами по себе, к примеру есть такая штука как EXPLAIN. У мну к примеру недавно на выборке с довольно хитрыми связями из 4 таблиц, в каждой >50к записей произошел затык. Помогла разбивка на 3 последовательных запроса ) Ваш же скрипт, вам виднее. В принципе можно, и кидать его в мемкэш, потом уже проверять есть ли там новая строчка или нет. Но это как мне кажется жуткий костыль, лучше уменьшить время выполнения самой выборки.
Так в том то и дело что на мой взгляд упростить запросы помоему нельзя. Индексы сделала, все запросы- то что нужно без лишнего... Даже не знаю что делать.
Я после откровений сноудена шапочку из фольги не снимаю. Хрен с ней с телепатией, главное что они мои мысли читать не могут ))
а от нас что хотите тогда? невидя ваши запросы и код, помочь почти нереально. так как один корявый запрос вполне может сильно нагибать сервер, даже если выглядит несложным.
Update.php Код (Text): <?php require('connection.php'); require ('checkUser.php'); $task=$_POST['task_id']; $row=$_POST['row_id']; $uName=$_POST['user_name']; $PRD_ID=$_POST['PRD_ID']; $Catalog_ID=$_POST['Catalog_ID']; if( $_POST['answer']==1 ) { $query="UPDATE ecnmatchingdetails SET RowStatus=2,Agent='".$uName."' , VendorAnswer='Yes', VendorComment='".$_POST['comments']."' where TaskID=".$task." and RowId=".$row; mysqli_query($con, $query); } else { if( $_POST['answer']==2 ) { $query="UPDATE ecnmatchingdetails SET RowStatus=2,Agent='".$uName."' , VendorAnswer='No',VendorReason='".$_POST['reapost']."', VendorComment='".$_POST['comments']."' where TaskID=".$task." and RowId=".$row; mysqli_query($con, $query); } else { if( $_POST['answer']==0 ) { $query="UPDATE ecnmatchingdetails SET RowStatus=0, Agent='' where TaskID=".$task." and RowId=".$row; mysqli_query($con, $query); } } } $query = "Update projects set LastUpdateDate ='".date('Y-m-d')."' where ProjectID=".$task; mysqli_query($con, $query); if( isset( $_POST['answer'])) { header( 'Location:..../WorkOnTaskECNMatching.php?id='.$task . '&start_task=0&Catalog_ID='.$Catalog_ID.'&prevID='.$PRD_ID.'&prevRow='.$row); exit(); } ?> Добавлено спустя 3 минуты 31 секунду: Initial.php Код (Text): <?php require('connection.php'); include 'checkUser.php'; $task_id=$_GET['id']; $start_task=$_GET['start_task']; $prevID=$_GET['prevID']; $EPID_finished=1; //this parameter will be 1 if we have another row with the same EPId or 0 if we dont have another row with this EPID //updating the end tag of the previous row $time = date("Y-m-d H:i:s"); if ($start_task==0){ //meaning we had a previous row because we came from submit $prevRow=$_GET['prevRow']; $query2="UPDATE ecnmatchingdetails SET end_tag='".$time."' where TaskID=".$task_id." and RowId=".$prevRow; mysqli_query($con, $query2); } /*********************************************** ECN "random" row choosing algorythm: **********************************************************/ /* 1. Check if the user started working just now or came here from hitting the submit button 2. If it is a new user (start_task=1), choose a random row, that is "new" (not locked and not finished) and has an EPID that noone is working on it 3. If there is no such EPID, for us the user is done - he will see "task ended" even though there are unfinished rows 4. If the user already working (start_task=0, PRD_ID)- choose a row with the same EPID he had before 5. If there is no such EPID do number 2 and numer 3. ** The rows are grouped not only by EPId but also by a catalog ************************************************************************************************************************************************/ $foundRow=0; if ($start_task == 0){ //we came from a submit button and already worked on an EPID $Catalog_ID=$_GET['Catalog_ID']; $query = "SELECT * FROM ecnmatchingdetails WHERE TaskID=".$task_id." AND PRD_ID=".$prevID." AND RowStatus=0"; $data = mysqli_query($con, $query); if (mysqli_num_rows($data) == 0) $EPID_finished=0; //We have some rows, now we need to choose one based on a catalogID. else { while ($row = mysqli_fetch_array($data)){ if ($row['Catalog_ID']==$Catalog_ID){ $foundRow=1; break; } } if ($foundRow==0) //we didnt find a row with a previous catalog ID { mysqli_data_seek($data, 0); $row = mysqli_fetch_array($data); } } } if ($start_task==1 OR $EPID_finished==0){ //If this user just started working or this EPID has no more rows $Catalog_ID=NULL; $query = "SELECT * FROM ecnmatchingdetails WHERE TaskID=".$task_id." AND RowStatus=0 AND PRD_ID NOT IN ( SELECT DISTINCT PRD_ID FROM ecnmatchingdetails WHERE TaskID=".$task_id." AND RowStatus=1) LIMIT 1"; $data = mysqli_query($con, $query); $row = mysqli_fetch_array($data); } /******************************************************************************************************/ //lock the row we are working on $query="UPDATE ecnmatchingdetails SET RowStatus=1 ,Agent='".$_SESSION['username']."' where TaskID=".$row['TaskID']." and RowId=".$row['RowId']; mysqli_query($con, $query); /******************************************************************************************************/ if($row['COUNTRY_ID']!=null) { $deal_id = $row['DEAL_ID']; $deal_name = $row['NAME']; $deal_URL = $row['URL']; $countryID = $row['COUNTRY_ID']; $Catalog_ID = $row['Catalog_ID']; $Catalog_NAME = $row['Catalog_NAME']; $upc = $row['UPC']; $mpn = $row['MPN']; $brand = $row['BRAND']; $ctlgID = $row['CTL_ID']; $Catalog_name=$row['Catalog_name']; $PRD_ID = $row['PRD_ID']; $ProductURL = $row['PRODUCT_URL']; $MatchingReason = $row['MATCHING_REASON']; $LastSortedDate = $row['LAST_SORTED_DATE']; $row_id = $row['RowId']; /******************************************************************************************************/ //EPID title $VUrl = 'http://...../query?Vr=0.1&Qy=AND(EQ(ATTR(29),' . $row['PRD_ID'] . '))&Sp=&Nr=1000&Sk=0&Fl=6+6&Hx=no'; $str = file_get_contents($VUrl); $str= str_replace('',' ',$str); $parse = explode(' ',$str); $EPIDtitle = $parse[1]; //Find this project type (ECN) details $query = "SELECT * FROM projecttypes JOIN projects ON projecttypes.TypeID=projects.ProjectType WHERE projects.ProjectID=".$row['TaskID']; $data = mysqli_query($con, $query); $row_2 = mysqli_fetch_array($data); $task_type =$row_2['TypeName']; $question=$row_2['ProjectQuestion']; $reasons=explode(',',$row_2['ValidReasons']); $reasonsHtml=""; for ($i = 0; $i <= sizeof($reasons)-1; $i++) { $reasonsHtml .= "<option value='v".($i+1)."'>".$reasons[$i]."</option>"; } $answers=explode(',',$row_2['ValidAnswers']); $answer_true= $answers[0]; $answer_false= $answers[1]; $answer_skip=$answers[2]; $guideurl=$row_2['GuidelinesURL']; } //no rows left to answer else { $query= "Select ProjectStatus from projects where ProjectID=".$task_id; $stat = mysqli_query($con,$query); $stArr = mysqli_fetch_array($stat); if($stArr['ProjectStatus'] <= 2) { $query = "Update projects set FinishDate ='".date('Y-m-d')."', ProjectStatus='3' where ProjectID=".$task_id; mysqli_query($con, $query); } echo '<script>taskEnd();</script>'; } //updating the start tag of the new row $query="UPDATE ecnmatchingdetails SET start_tag='".$time."' where TaskID=".$task_id." and RowId=".$row_id; mysqli_query($con, $query); switch ($row['COUNTRY_ID']) { case 1: $linkToSite="http:/...."; break; case 44: $linkToSite="..."; break; case 250: $linkToSite="..."; break; case 36: $linkToSite="..."; break; case 276: $linkToSite="...."; break; default: $linkToSite="...."; } ?> Добавлено спустя 2 минуты 19 секунд: Так бы и сказали что хотите код увидеть А что я от вас хотела - я спросила - можно ли в PHP одновременно пока юзер видеть VIEW делать все query чтоб работало паралельно а не один скрипт за другим. Хотя уверена (или по крайней мере надеюсь) прочтя мой скрипт, вы найдете кучу других способов его улучшения
Да уж. В запросы вставляются не данные из POST, а переменные, скопированные из POST. Это, мягко говоря, не защита, а энтропия.
Ваш ответ конечно же очень помогает Четко обьяснила проблему, приняли во внимания что я новичок, ответили на тот вопрос который я задала, прислали линк на возможное решение... У меня нет проблемы с защитой. Точнее - такого вопроса просто нет.
прежде чем лечить, надо поставить диагноз. для начала надо узнать сколько времени выполняется каждый запрос. может статься, что у вас тупо соединение с базой устанавливается две секунды — такое тоже бывает из-за сетевых проблем. я бы посоветовал писать данные в файл лога.