I'm in the middle of updating/reworking some database code and I was wondering, what I should really expect from using prepared statements.
Take this example code:
$values = '';
for ($i = 0; $i < $count; $i++) {
$name = mysql_real_escape_string ($list[$i][1]);
$voc = mysql_real_escape_string ($list[$i][3]);
$lev = $list[$it][2];
$lev = is_numeric ($lev)? $lev : 0;
$values .= ($values == '')? "('$name', '$voc', $lev)" : ", ('$name', '$voc', $lev)";
}
if ($values != '') {
$core->query ("INSERT INTO onlineCList (name, voc, lev) VALUES $values;");
}
Now, apart from the obvious gain in readability (, sanity) and the fact that max_packet_size
stops being an issue, am I supposed to expect any changes in performance when I recode this to use prepared statements? I'm connecting remotely to the MySQL server, and I worry that sending multiple small packets would be significantly slower then sending one big packet. If this is the case, can MySQLi/mysqlnd cache these packets?
Another example:
$names = '';
while ($row = mysql_fetch_array ($result, MYSQL_ASSOC)) {
$name = mysql_real_escape_string($row['name']);
$names .= ($names == '') ? "'$name'" : ", '$name'";
}
if ($names != '') {
$core->query ("UPDATE onlineActivity SET online = NULL WHERE name IN ($names) AND online = 1;");
}
As above, should I expect the unexpected, after recoding this to use prepared statements? Does it make any difference for the MySQL server, if it has to run one query with a big IN clause, or multiple prepared queries with equality checks (.. WHERE name = $name AND ..
)?
Assume that everything is properly indexed.
Prepared statements are much faster when you have to run the same statement multiple times, with different data. Thats because SQL will validate the query only once, whereas if you just use a statement it will validate the query each time.
Benefits of prepared statements are: efficiency, because they can be used repeatedly without re-compiling. security, by reducing or eliminating SQL injection attacks.
You should always prefer working with prepared statements for the security benefits. They all but eliminate vulnerability to SQL injection, without you having to worry about SQL-escaping values. If you have a query that doesn't run often, though (less than once per request), a prepared statement can take longer to run.
Prepared statements are generally faster than regular queries if you're repeatedly running the same query. Performance is nice but the real win with PreparedStatements is the parameter binding can do done via the API rather than string concatenation.
Normally, if you just use a prepared statement in place of a plain query, it's marginally slower since the query is prepared and executed in two steps instead of one. Prepared statements become faster only when you're preparing the statement and then executing it multiple times.
However, in this case you're using mysql_real_escape_string
, which does a roundtrip to the database. Even worse, you're doing it inside a loop, so, executing it multiple times per query. So, in this case replacing all of those roundtrips with a single prepared statement is a win-win-win.
Regarding your last question, there's no reason you can't use the same query with a prepared statement as you would through the normal query parser (i.e. no reason to execute one version with an IN and the other with a bunch of ORs). The prepared statement can have IN (?, ?, ?)
, and then you just bind that number of parameters.
My advice would be to always use prepared statements. In cases where they add a marginal performance overhead, they're still worth it for the security (no SQL injection) and readability benefits. For sure, anytime you find yourself resorting to mysql_real_escape_string
, you should use a prepared statement instead. (For simple one-off queries where there's no need to escape variable inputs, they aren't strictly necessary.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With