Reputation: 4886
I am very weak in Mysql
I had to update the question id of an answer table according to some condition I have written following script but it takes more than 700 Seconds to execute because the data is huge,
Can any one please Help me fix this
function UpdateAnswer()
{
ini_set('max_execution_time', 800);
$users= DB::select(DB::raw("select * from users where role!='admin_dd' and role!='sales_dd' "));
foreach($users as $user)
{
$answers= DB::select(DB::raw("select * from answers where user_id='$user->id' "));
foreach($answers as $answer)
{
$questionDetNew = '';
$questionDetOld = DB::select(DB::raw("select * from questions where id='$answer->question_id' "));
if(is_array($questionDetOld))
echo "questionDetOld true";
foreach ($questionDetOld as $question) {
# code...
echo "<br/>";
echo $question->id;
echo $question->question_text;
echo $user->event; echo"<br/>";
$questionDetNew= DB::select(DB::raw("select * from questions where question_text='$question->question_text' and event='$user->event' and question_group='$question->question_group' "));
}
if(is_array($questionDetNew)){
foreach ($questionDetNew as $questionx) {
# code..
if($questionx->id!=NULL){
echo "Updated<br/>";
//DB::select(DB::raw("update answers set question_id='$questionx->id' where id='$answer->id' "));
}
else {
echo "Its already existing ";
}
}
}
}
}
}
UPDATE
I came up with this following According to the comments provided but still the execution time is not much difference
ini_set('max_execution_time', 800);
$users= DB::select(DB::raw("select * from users where role!='admin_dd' and role!='sales_dd' "));
// $users = User::where('role','!=','admin_dd')->orWhere('role','!=','sales_dd')->orderby('name')->get();
$answers= DB::select(DB::raw("select * from answers "));
$questionDetOld = DB::select(DB::raw("select * from questions"));
foreach($users as $user)
{
foreach ($answers as $answer) {
if($answer->user_id==$user->id)
{
foreach($questionDetOld as $question)
{
if($question->id==$answer->question_id )
{
echo "<br/>";
echo $question->id;
echo $question->question_text;
echo $user->event; echo"<br/>";
//$questionDetNew= DB::select(DB::raw("select * from questions where question_text='$question->question_text' and event='$user->event' and question_group='$question->question_group' "));
foreach ($questionDetOld as $questionx) {
if($questionx->question_text==$question->question_text && $questionx->event==$user->event && $questionx->question_group==$question->question_group)
{
echo "Updated<br/>";
}
}
}
}
}
}
}
Upvotes: 3
Views: 170
Reputation: 644
First of all, do you have correct indexes in database? Second, you have too much loops inside loops. On large amounts of data it can be really slow. You can optimize this script by preparing arrays, indexed by key fields. Here is an example:
ini_set('max_execution_time', 800);
$userIds = array();
$users= DB::select(DB::raw("select * from users where role!='admin_dd' and role!='sales_dd' "));
forach ($users as $user) {
$userIds[] = $user->id;
}
$questionIds = array();
$answers_tmp= DB::select(DB::raw("select * from answers where user_id in (".implode(',',$userIds).')'));
foreach ($answers_tmp as $answer) {
$answers[$answer->user_id][] = $answer;
$questionIds[] = $answer->question_id;
}
$questionDetOld_tmp = DB::select(DB::raw("select * from questions where id in (".implode(',',$questionIds).')'));
foreach ($questionDetOld_tmp as $question) {
$questionDetOld[$question->id][] = $question;
}
foreach($users as $user)
{
if (isset($answers[$user->id]))
{
foreach ($answers[$user->id] as $answer)
{
if (isset($questionDetOld[$answer->question_id]))
{
foreach($questionDetOld[$answer->question_id] as $question)
{
echo "<br/>";
echo $question->id;
echo $question->question_text;
echo $user->event; echo"<br/>";
//$questionDetNew= DB::select(DB::raw("select * from questions where question_text='$question->question_text' and event='$user->event' and question_group='$question->question_group' "));
foreach ($questionDetOld_tmp as $questionx)
{
if($questionx->question_text==$question->question_text && $questionx->event==$user->event && $questionx->question_group==$question->question_group)
{
echo "Updated<br/>";
}
}
}
}
}
}
}
Upvotes: 1
Reputation: 5157
To avoid queries inside loops, use it like this
$INuserdata[] = array();
$INanswerdata[] = array();
$users= DB::select(DB::raw("select * from users where role!='admin_dd' and role!='sales_dd' "));
foreach($users as $user)
$INuserdata[] = $user->id;
$answers= DB::select(DB::raw("select * from answers where user_id IN (".implode(',',$INuserdata).")"));
foreach($answers as $answer)
$INanswerdata[] = $answer->question_id;
$questionDetOld = DB::select(DB::raw("select * from questions where id IN (".implode(',',$INanswerdata).")"));
Upvotes: 1