0

I have a fairly simple query:

$r = $dbh->prepare("SELECT user FROM this_users_rented WHERE user_by=:user LIMIT $offset, $rowsperpage");
$r->bindParam(':user', $userdata['username']);
$r->execute();

($offset and $rowsperpage is representing the offset of the list, based on the current page, and how many records there should be shown per page. (Example: 0,100))

This will gather all the data from this_users_rented where the user_by is = $userdata['username'];

I am running this query in a WHILE LOOP:

    while($data=$r->fetch()):
      //Get data from table: this_users_rented to print out in the while loop.
          $stmt = $dbh->prepare("SELECT * FROM xeon_users_rented_stats WHERE urs_user=:user");
          $stmt->bindParam(':user', $data['user']);
          $stmt->execute();
          $refStat = $stmt->fetch();

    endwhile;

So, imagine that there is hundreds of records in the $r query - yielding hundreds of queries to be run (due to the lack of optimization of the $stmt query)

So my question is, how can I optimize the $stmt query?

3
  • 2
    Why don't you use a join instead? Commented Aug 24, 2014 at 16:41
  • @VMai How would that work? Could you provide a simple example, using JOIN function? Commented Aug 24, 2014 at 16:42
  • Also you should prepare a statement outside of a loop; doing it within the loop completely negates the purpose of preparing the query. Prepare once, execute many times. Commented Aug 24, 2014 at 16:57

1 Answer 1

0

You have a LIMIT clause on your user table so you could use following trick to overcome the MySQL limitation that you can't use a LIMIT clause in a subselect for the preparing of the statement:

$r = $dbh->prepare("
               SELECT x.* 
               FROM xeon_users_rented_stats x
               INNER JOIN (
                   SELECT 
                       user_by 
                   FROM this_users_rented 
                   WHERE user_by = :user 
                   LIMIT $offset, $rowsperpage
               ) t
               ON x.urs_user = t.user_by
               ORDER BY x.urs_user;"
      );
$r->bindParam(':user', $userdata['username']);
$r->execute();
while($refstat=$r->fetch()){
    // do what you want to do ...
}

This trick changes the subselect to a materialized derived table where you can use LIMIT.

Note:

Of course you should test the sql statement in a sql client first to make sure you get the data you need.

2
  • That's the alias name for the table xeon_users_rented_stats. Had I forgotten to edit in. Done now. Commented Aug 25, 2014 at 12:55
  • Thanks! Could you please provide an example of $r, that I Can use in a while loop. Using it now, no records are shown Commented Aug 25, 2014 at 13:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.