1

I've got a SQL query within a foreach loop. Sometimes there can be many, and I mean a lot of queries to do, depending on several criteria, up to 78 queries potentially.

Now, I know that premature optimisation is root cause of all evil, but I don't want to see 78 queries - it's just not healthy.

Here's the code:

$crumbs = explode(",", $user['data']['depts']);

foreach ($crumbs as &$value) {
    $data = $db->query("SELECT id FROM tbl_depts WHERE id = '" . $value . "'");
    $crumb = $data->fetch_assoc();
    $dsn = $db->query("SELECT msg, datetime FROM tbl_motd WHERE deptid = '" . $value . "'");
    $motd = $dsn->fetch_assoc();
    if ($motd['msg'] != "") {
        <?php echo $motd['msg']; ?>
    }
}

Can I make it any better?

3
  • Aside from the optimizations below, you might want to consider making it a stored procedure instead of a straight select to improve performance. Commented Jun 27, 2011 at 2:09
  • be aware that this code is vulnerable to sql injection attacks. Commented Jun 27, 2011 at 11:53
  • Hello Daniel, why is this the case? The data is only getting an array, which would have been sanitised before putting in. Aldo, $user['data'] and its children are also sanitised before this code. Commented Jun 27, 2011 at 11:55

2 Answers 2

1

Use IN MySQL operator to search over a set of values for id:

$ids = '"' . implode('", "',$crumbs) . '"';
$query1 = "SELECT id FROM tbl_depts WHERE id IN (" . $ids . ")";
$query2 = "SELECT msg, datetime FROM tbl_motd WHERE deptid IN (" . $ids . ")";

And so you will not need to retrieve all data you need using foreach loop, so you will have only 2 queries instead of 78.

Example: I have a table named table with 10 records which ids are: 1,2,3,4,5,6,7,8,9,10 (auto-incremented). I know I need records with ids 1,5,8. My query will be:

$sql = "SELECT * FROM `table` WHERE id in (1,5,8);";

And I don't understand why do you need to use & operator in foreach loop if you don't modify the $crubms arrays values.

Sign up to request clarification or add additional context in comments.

6 Comments

So I would replace the two queries above with this, but rewrite the code itself?
It's just habit that I put & operator in.
@Shamil, Yes. You will have to rewrite the code since it uses another approach.
@Shamil it's a bad habit then. You might occasionally modify any array in your program and it will be hard to find out where an error is hidden.
Using the & operator will make the program run slightly faster as the program doesn't need to allocate memory to store each $value in.
|
1

I think this is want you want.

SELECT msg, datetime
FROM tbl_depts td
INNER JOIN tbl_motd tm ON td.id = tm.deptid

2 Comments

which one should I replace it with?
I did not really looked into the logic of queries, but I think you've forgotten WHERE somewhere. I think OPs query result is restricted by a set of particular ids. Should be INNER JOIN tbl_motd tm ON td.id = tm.deptid WHERE td.id in (<set of ids>), probably?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.