I need to count the number of rows from different(!) tables and save the results for some kind of statistic. The script is quite simple and working as expected, but I’m wondering if it’s better to use a single query with (in this case) 8 subqueries, or if I should use separate 8 queries or if there’s even a better, faster and more advanced solution…
I’m using MySQLi with prepared statements, so the single query could look like this:
$sql = 'SELECT (SELECT COUNT(cat1_id) FROM `cat1`), (SELECT COUNT(cat2_id) FROM `cat2`), (SELECT COUNT(cat2_id) FROM `cat2` WHERE `date` >= DATE(NOW())), (SELECT COUNT(cat3_id) FROM `cat3`), (SELECT COUNT(cat4_id) FROM `cat4`), (SELECT COUNT(cat5_id) FROM `cat5`), (SELECT COUNT(cat6_id) FROM `cat6`), (SELECT COUNT(cat7_id) FROM `cat7`)'; $stmt = $db->prepare($sql); $stmt->execute(); $stmt->bind_result($var1, $var2, $var3, $var4, $var5, $var6, $var7, $var8); $stmt->fetch(); $stmt->free_result(); $stmt->close();
while the seperate queries would look like this (x 8):
$sql = 'SELECT COUNT(cat1_id) FROM `cat1`'; $stmt = $db->prepare($sql); $stmt->execute(); $stmt->bind_result($var1); $stmt->fetch(); $stmt->free_result(); $stmt->close();
so, which would be faster or “better style” related to this kind of query (e.g. statistics, counter..)
Advertisement
Answer
Regarding to TerryE’s example and the advice to use multi_query(!), I checked the manual and changed the script to fit my needs.. finally I got a solution that looks like this:
$sql = 'SELECT COUNT(cat1_id) as `cat1` FROM `cat1`;'; $sql .= 'SELECT COUNT(cat2_id) as `cat2` FROM `cat2`;'; $sql .= 'SELECT COUNT(cat2_id) as `cat2_b` FROM `cat2` WHERE `date` >= DATE(NOW());'; $sql .= 'SELECT COUNT(cat3_id) as `cat3` FROM `cat3`;'; $sql .= 'SELECT COUNT(cat4_id) as `cat4` FROM `cat4`;'; $sql .= 'SELECT COUNT(cat5_id) as `cat5` FROM `cat5`;'; $sql .= 'SELECT COUNT(cat6_id) as `cat6` FROM `cat6`;'; $sql .= 'SELECT COUNT(cat7_id) as `cat7` FROM `cat7`;'; if ($db->multi_query($sql)) { do { if ($stmt = $db->store_result()) { while ($row = $stmt->fetch_assoc()) { foreach ($row as $key => $value) { $count[$key] = $value; } } $stmt->free_result(); } } while ($db->more_results() && $db->next_result()); }
There are some differences to TerryE’s example, but the result is the same. I’m aware that there are 7 line at the beginning that are almost identical, but as soon as I need a WHERE clause or something else, I prefer this solution to a foreach loop where I’d need to add queries manually or use exceptions with if { ... }
…
As far as I can see, there should be no problem with my solution, or did I miss something?